5.1 组件架构设计

5.1.1 组件设计原则

graph TD
    A[组件设计原则] --> B[单一职责]
    A --> C[可复用性]
    A --> D[可组合性]
    A --> E[可测试性]
    A --> F[可维护性]
    
    B --> G[功能聚焦]
    B --> H[职责明确]
    
    C --> I[通用接口]
    C --> J[配置灵活]
    
    D --> K[组件嵌套]
    D --> L[插槽机制]
    
    E --> M[单元测试]
    E --> N[集成测试]
    
    F --> O[代码清晰]
    F --> P[文档完善]

5.1.2 基础组件类

// 基础组件类
class Component {
    constructor(element, options = {}) {
        this.element = element;
        this.options = this.mergeOptions(this.getDefaultOptions(), options);
        this.state = {};
        this.children = new Map();
        this.eventListeners = new Map();
        this.isDestroyed = false;
        
        this.init();
    }
    
    // 获取默认选项
    getDefaultOptions() {
        return {
            className: '',
            autoRender: true,
            autoDestroy: true
        };
    }
    
    // 合并选项
    mergeOptions(defaults, options) {
        return Object.assign({}, defaults, options);
    }
    
    // 初始化组件
    init() {
        this.beforeCreate();
        this.create();
        this.afterCreate();
        
        if (this.options.autoRender) {
            this.render();
        }
        
        this.setupEvents();
        this.mounted();
    }
    
    // 生命周期钩子
    beforeCreate() {
        // 组件创建前
    }
    
    create() {
        // 组件创建
        this.setupState();
        this.setupTemplate();
    }
    
    afterCreate() {
        // 组件创建后
    }
    
    mounted() {
        // 组件挂载完成
    }
    
    beforeUpdate() {
        // 更新前
    }
    
    updated() {
        // 更新后
    }
    
    beforeDestroy() {
        // 销毁前
    }
    
    destroyed() {
        // 销毁后
    }
    
    // 设置状态
    setupState() {
        this.state = this.getInitialState();
    }
    
    getInitialState() {
        return {};
    }
    
    // 设置模板
    setupTemplate() {
        const template = this.getTemplate();
        if (template) {
            this.element.innerHTML = template;
        }
    }
    
    getTemplate() {
        return '';
    }
    
    // 渲染组件
    render() {
        this.beforeUpdate();
        this.updateDOM();
        this.updated();
    }
    
    updateDOM() {
        // 子类实现具体的 DOM 更新逻辑
    }
    
    // 设置事件
    setupEvents() {
        const events = this.getEvents();
        Object.entries(events).forEach(([selector, handlers]) => {
            Object.entries(handlers).forEach(([event, handler]) => {
                this.on(selector, event, handler);
            });
        });
    }
    
    getEvents() {
        return {};
    }
    
    // 事件绑定
    on(selector, event, handler) {
        const elements = selector === 'this' ? [this.element] : 
                        this.element.querySelectorAll(selector);
        
        elements.forEach(el => {
            const boundHandler = handler.bind(this);
            el.addEventListener(event, boundHandler);
            
            // 存储事件监听器以便后续清理
            const key = `${selector}-${event}`;
            if (!this.eventListeners.has(key)) {
                this.eventListeners.set(key, []);
            }
            this.eventListeners.get(key).push({ element: el, handler: boundHandler });
        });
    }
    
    // 触发事件
    emit(eventName, detail = {}) {
        const event = new CustomEvent(eventName, {
            detail,
            bubbles: true,
            cancelable: true
        });
        this.element.dispatchEvent(event);
    }
    
    // 状态管理
    setState(newState, shouldRender = true) {
        const oldState = { ...this.state };
        this.state = { ...this.state, ...newState };
        
        this.emit('state-changed', {
            oldState,
            newState: this.state,
            changedKeys: Object.keys(newState)
        });
        
        if (shouldRender) {
            this.render();
        }
    }
    
    getState(key) {
        return key ? this.state[key] : this.state;
    }
    
    // 子组件管理
    addChild(name, component) {
        this.children.set(name, component);
        return component;
    }
    
    getChild(name) {
        return this.children.get(name);
    }
    
    removeChild(name) {
        const child = this.children.get(name);
        if (child && typeof child.destroy === 'function') {
            child.destroy();
        }
        this.children.delete(name);
    }
    
    // 查找元素
    $(selector) {
        return this.element.querySelector(selector);
    }
    
    $$(selector) {
        return this.element.querySelectorAll(selector);
    }
    
    // 销毁组件
    destroy() {
        if (this.isDestroyed) return;
        
        this.beforeDestroy();
        
        // 清理事件监听器
        this.eventListeners.forEach(listeners => {
            listeners.forEach(({ element, handler }) => {
                element.removeEventListener(event, handler);
            });
        });
        this.eventListeners.clear();
        
        // 销毁子组件
        this.children.forEach(child => {
            if (typeof child.destroy === 'function') {
                child.destroy();
            }
        });
        this.children.clear();
        
        // 清理 DOM
        if (this.options.autoDestroy && this.element.parentNode) {
            this.element.parentNode.removeChild(this.element);
        }
        
        this.isDestroyed = true;
        this.destroyed();
    }
}

// 使用示例:创建一个按钮组件
class Button extends Component {
    getDefaultOptions() {
        return {
            ...super.getDefaultOptions(),
            text: 'Button',
            variant: 'primary',
            size: 'medium',
            disabled: false,
            loading: false
        };
    }
    
    getInitialState() {
        return {
            clicked: false,
            loading: this.options.loading
        };
    }
    
    getTemplate() {
        return `
            <button class="btn btn-${this.options.variant} btn-${this.options.size}" 
                    ${this.options.disabled ? 'disabled' : ''}>
                <span class="btn-content">${this.options.text}</span>
                <span class="btn-loading" style="display: none;">⏳</span>
            </button>
        `;
    }
    
    getEvents() {
        return {
            'button': {
                'click': this.handleClick
            }
        };
    }
    
    handleClick(event) {
        if (this.state.loading || this.options.disabled) {
            event.preventDefault();
            return;
        }
        
        this.setState({ clicked: true });
        
        this.emit('button-click', {
            originalEvent: event,
            button: this
        });
        
        // 重置点击状态
        setTimeout(() => {
            this.setState({ clicked: false });
        }, 150);
    }
    
    setLoading(loading) {
        this.setState({ loading });
        this.updateLoadingState();
    }
    
    updateLoadingState() {
        const button = this.$('button');
        const content = this.$('.btn-content');
        const loadingIcon = this.$('.btn-loading');
        
        if (this.state.loading) {
            button.disabled = true;
            content.style.display = 'none';
            loadingIcon.style.display = 'inline';
        } else {
            button.disabled = this.options.disabled;
            content.style.display = 'inline';
            loadingIcon.style.display = 'none';
        }
    }
    
    setText(text) {
        this.options.text = text;
        this.$('.btn-content').textContent = text;
    }
    
    setDisabled(disabled) {
        this.options.disabled = disabled;
        this.$('button').disabled = disabled || this.state.loading;
    }
}

5.1.3 组件工厂

class ComponentFactory {
    constructor() {
        this.components = new Map();
        this.instances = new WeakMap();
    }
    
    // 注册组件
    register(name, componentClass, options = {}) {
        this.components.set(name, {
            class: componentClass,
            options: options
        });
    }
    
    // 创建组件实例
    create(name, element, options = {}) {
        const componentInfo = this.components.get(name);
        if (!componentInfo) {
            throw new Error(`组件 "${name}" 未注册`);
        }
        
        const mergedOptions = { ...componentInfo.options, ...options };
        const instance = new componentInfo.class(element, mergedOptions);
        
        // 存储实例引用
        this.instances.set(element, instance);
        
        return instance;
    }
    
    // 获取元素关联的组件实例
    getInstance(element) {
        return this.instances.get(element);
    }
    
    // 自动初始化页面中的组件
    autoInit(container = document) {
        this.components.forEach((componentInfo, name) => {
            const elements = container.querySelectorAll(`[data-component="${name}"]`);
            elements.forEach(element => {
                if (!this.instances.has(element)) {
                    const options = this.parseDataAttributes(element);
                    this.create(name, element, options);
                }
            });
        });
    }
    
    // 解析 data 属性
    parseDataAttributes(element) {
        const options = {};
        Array.from(element.attributes).forEach(attr => {
            if (attr.name.startsWith('data-') && attr.name !== 'data-component') {
                const key = attr.name.substring(5).replace(/-([a-z])/g, (g) => g[1].toUpperCase());
                let value = attr.value;
                
                // 尝试解析 JSON
                try {
                    value = JSON.parse(value);
                } catch (e) {
                    // 保持原始字符串值
                }
                
                options[key] = value;
            }
        });
        return options;
    }
    
    // 销毁所有组件实例
    destroyAll(container = document) {
        const elements = container.querySelectorAll('[data-component]');
        elements.forEach(element => {
            const instance = this.instances.get(element);
            if (instance && typeof instance.destroy === 'function') {
                instance.destroy();
            }
        });
    }
}

// 全局组件工厂实例
const componentFactory = new ComponentFactory();

// 注册组件
componentFactory.register('button', Button);
componentFactory.register('modal', Modal);
componentFactory.register('dropdown', Dropdown);

// 自动初始化
document.ready = function() {
    componentFactory.autoInit();
};

5.2 生命周期管理

5.2.1 生命周期钩子系统

class LifecycleManager {
    constructor() {
        this.hooks = new Map();
        this.globalHooks = new Map();
    }
    
    // 注册生命周期钩子
    registerHook(component, hookName, callback) {
        if (!this.hooks.has(component)) {
            this.hooks.set(component, new Map());
        }
        
        const componentHooks = this.hooks.get(component);
        if (!componentHooks.has(hookName)) {
            componentHooks.set(hookName, []);
        }
        
        componentHooks.get(hookName).push(callback);
    }
    
    // 注册全局钩子
    registerGlobalHook(hookName, callback) {
        if (!this.globalHooks.has(hookName)) {
            this.globalHooks.set(hookName, []);
        }
        this.globalHooks.get(hookName).push(callback);
    }
    
    // 执行钩子
    async executeHook(component, hookName, ...args) {
        const results = [];
        
        // 执行全局钩子
        const globalCallbacks = this.globalHooks.get(hookName) || [];
        for (const callback of globalCallbacks) {
            try {
                const result = await callback(component, ...args);
                results.push(result);
            } catch (error) {
                console.error(`全局钩子 ${hookName} 执行错误:`, error);
            }
        }
        
        // 执行组件特定钩子
        const componentHooks = this.hooks.get(component);
        if (componentHooks) {
            const callbacks = componentHooks.get(hookName) || [];
            for (const callback of callbacks) {
                try {
                    const result = await callback(...args);
                    results.push(result);
                } catch (error) {
                    console.error(`组件钩子 ${hookName} 执行错误:`, error);
                }
            }
        }
        
        return results;
    }
    
    // 清理组件钩子
    clearComponentHooks(component) {
        this.hooks.delete(component);
    }
}

// 增强的组件基类
class EnhancedComponent extends Component {
    constructor(element, options = {}) {
        super(element, options);
        this.lifecycleManager = new LifecycleManager();
        this.setupLifecycleHooks();
    }
    
    setupLifecycleHooks() {
        // 可以在这里设置默认的生命周期钩子
    }
    
    // 重写生命周期方法以支持钩子
    async beforeCreate() {
        await this.lifecycleManager.executeHook(this, 'beforeCreate');
        super.beforeCreate();
    }
    
    async create() {
        await this.lifecycleManager.executeHook(this, 'create');
        super.create();
    }
    
    async afterCreate() {
        await this.lifecycleManager.executeHook(this, 'afterCreate');
        super.afterCreate();
    }
    
    async mounted() {
        await this.lifecycleManager.executeHook(this, 'mounted');
        super.mounted();
    }
    
    async beforeUpdate() {
        await this.lifecycleManager.executeHook(this, 'beforeUpdate');
        super.beforeUpdate();
    }
    
    async updated() {
        await this.lifecycleManager.executeHook(this, 'updated');
        super.updated();
    }
    
    async beforeDestroy() {
        await this.lifecycleManager.executeHook(this, 'beforeDestroy');
        super.beforeDestroy();
    }
    
    async destroyed() {
        await this.lifecycleManager.executeHook(this, 'destroyed');
        this.lifecycleManager.clearComponentHooks(this);
        super.destroyed();
    }
    
    // 添加生命周期钩子的便捷方法
    onBeforeCreate(callback) {
        this.lifecycleManager.registerHook(this, 'beforeCreate', callback);
    }
    
    onCreate(callback) {
        this.lifecycleManager.registerHook(this, 'create', callback);
    }
    
    onAfterCreate(callback) {
        this.lifecycleManager.registerHook(this, 'afterCreate', callback);
    }
    
    onMounted(callback) {
        this.lifecycleManager.registerHook(this, 'mounted', callback);
    }
    
    onBeforeUpdate(callback) {
        this.lifecycleManager.registerHook(this, 'beforeUpdate', callback);
    }
    
    onUpdated(callback) {
        this.lifecycleManager.registerHook(this, 'updated', callback);
    }
    
    onBeforeDestroy(callback) {
        this.lifecycleManager.registerHook(this, 'beforeDestroy', callback);
    }
    
    onDestroyed(callback) {
        this.lifecycleManager.registerHook(this, 'destroyed', callback);
    }
}

5.2.2 组件状态管理

class StateManager {
    constructor(initialState = {}) {
        this.state = { ...initialState };
        this.watchers = new Map();
        this.computed = new Map();
        this.computedCache = new Map();
        this.mutations = new Map();
        this.actions = new Map();
    }
    
    // 获取状态
    getState(path) {
        if (!path) return this.state;
        
        return path.split('.').reduce((obj, key) => {
            return obj && obj[key] !== undefined ? obj[key] : undefined;
        }, this.state);
    }
    
    // 设置状态
    setState(path, value) {
        const keys = path.split('.');
        const lastKey = keys.pop();
        const target = keys.reduce((obj, key) => {
            if (!obj[key]) obj[key] = {};
            return obj[key];
        }, this.state);
        
        const oldValue = target[lastKey];
        target[lastKey] = value;
        
        // 触发观察者
        this.notifyWatchers(path, value, oldValue);
        
        // 清除相关的计算属性缓存
        this.clearComputedCache(path);
    }
    
    // 批量更新状态
    updateState(updates) {
        Object.entries(updates).forEach(([path, value]) => {
            this.setState(path, value);
        });
    }
    
    // 监听状态变化
    watch(path, callback, options = {}) {
        if (!this.watchers.has(path)) {
            this.watchers.set(path, []);
        }
        
        const watcher = {
            callback,
            immediate: options.immediate || false,
            deep: options.deep || false
        };
        
        this.watchers.get(path).push(watcher);
        
        // 立即执行
        if (watcher.immediate) {
            callback(this.getState(path), undefined);
        }
        
        // 返回取消监听的函数
        return () => {
            const watchers = this.watchers.get(path);
            if (watchers) {
                const index = watchers.indexOf(watcher);
                if (index > -1) {
                    watchers.splice(index, 1);
                }
            }
        };
    }
    
    // 通知观察者
    notifyWatchers(path, newValue, oldValue) {
        // 精确匹配
        const exactWatchers = this.watchers.get(path) || [];
        exactWatchers.forEach(watcher => {
            watcher.callback(newValue, oldValue);
        });
        
        // 深度监听
        this.watchers.forEach((watchers, watchPath) => {
            if (watchPath !== path && (path.startsWith(watchPath + '.') || watchPath.startsWith(path + '.'))) {
                watchers.forEach(watcher => {
                    if (watcher.deep) {
                        watcher.callback(this.getState(watchPath), undefined);
                    }
                });
            }
        });
    }
    
    // 计算属性
    computed(name, getter, dependencies = []) {
        this.computed.set(name, { getter, dependencies });
        
        // 监听依赖变化
        dependencies.forEach(dep => {
            this.watch(dep, () => {
                this.computedCache.delete(name);
            });
        });
    }
    
    // 获取计算属性
    getComputed(name) {
        if (this.computedCache.has(name)) {
            return this.computedCache.get(name);
        }
        
        const computedInfo = this.computed.get(name);
        if (!computedInfo) {
            throw new Error(`计算属性 "${name}" 不存在`);
        }
        
        const value = computedInfo.getter(this.state);
        this.computedCache.set(name, value);
        return value;
    }
    
    // 清除计算属性缓存
    clearComputedCache(changedPath) {
        this.computed.forEach((computedInfo, name) => {
            const shouldClear = computedInfo.dependencies.some(dep => 
                changedPath.startsWith(dep) || dep.startsWith(changedPath)
            );
            
            if (shouldClear) {
                this.computedCache.delete(name);
            }
        });
    }
    
    // 注册 mutation
    registerMutation(name, mutator) {
        this.mutations.set(name, mutator);
    }
    
    // 提交 mutation
    commit(name, payload) {
        const mutator = this.mutations.get(name);
        if (!mutator) {
            throw new Error(`Mutation "${name}" 不存在`);
        }
        
        mutator(this.state, payload);
        this.notifyWatchers('', this.state, {});
    }
    
    // 注册 action
    registerAction(name, action) {
        this.actions.set(name, action);
    }
    
    // 分发 action
    async dispatch(name, payload) {
        const action = this.actions.get(name);
        if (!action) {
            throw new Error(`Action "${name}" 不存在`);
        }
        
        const context = {
            state: this.state,
            getState: this.getState.bind(this),
            setState: this.setState.bind(this),
            commit: this.commit.bind(this),
            dispatch: this.dispatch.bind(this)
        };
        
        return await action(context, payload);
    }
}

// 带状态管理的组件
class StatefulComponent extends EnhancedComponent {
    constructor(element, options = {}) {
        super(element, options);
        this.stateManager = new StateManager(this.getInitialState());
        this.setupStateManagement();
    }
    
    setupStateManagement() {
        // 设置计算属性
        this.setupComputed();
        
        // 设置 mutations
        this.setupMutations();
        
        // 设置 actions
        this.setupActions();
        
        // 设置状态监听
        this.setupWatchers();
    }
    
    setupComputed() {
        // 子类实现
    }
    
    setupMutations() {
        // 子类实现
    }
    
    setupActions() {
        // 子类实现
    }
    
    setupWatchers() {
        // 子类实现
    }
    
    // 重写状态方法
    setState(path, value) {
        this.stateManager.setState(path, value);
        this.render();
    }
    
    getState(path) {
        return this.stateManager.getState(path);
    }
    
    watch(path, callback, options) {
        return this.stateManager.watch(path, callback, options);
    }
    
    computed(name, getter, dependencies) {
        this.stateManager.computed(name, getter, dependencies);
    }
    
    getComputed(name) {
        return this.stateManager.getComputed(name);
    }
    
    commit(name, payload) {
        this.stateManager.commit(name, payload);
        this.render();
    }
    
    dispatch(name, payload) {
        return this.stateManager.dispatch(name, payload);
    }
}

5.3 组件通信机制

5.3.1 事件总线

class EventBus {
    constructor() {
        this.events = new Map();
        this.onceEvents = new Set();
        this.maxListeners = 10;
    }
    
    // 监听事件
    on(eventName, callback, context = null) {
        if (!this.events.has(eventName)) {
            this.events.set(eventName, []);
        }
        
        const listeners = this.events.get(eventName);
        
        // 检查监听器数量
        if (listeners.length >= this.maxListeners) {
            console.warn(`事件 "${eventName}" 的监听器数量超过限制 (${this.maxListeners})`);
        }
        
        const listener = {
            callback,
            context,
            id: Symbol('listener')
        };
        
        listeners.push(listener);
        
        // 返回取消监听的函数
        return () => this.off(eventName, listener.id);
    }
    
    // 监听一次
    once(eventName, callback, context = null) {
        const listener = {
            callback,
            context,
            id: Symbol('listener')
        };
        
        this.onceEvents.add(listener.id);
        
        const unsubscribe = this.on(eventName, (...args) => {
            callback.apply(context, args);
            unsubscribe();
            this.onceEvents.delete(listener.id);
        }, context);
        
        return unsubscribe;
    }
    
    // 取消监听
    off(eventName, listenerId = null) {
        if (!this.events.has(eventName)) return;
        
        const listeners = this.events.get(eventName);
        
        if (listenerId) {
            // 移除特定监听器
            const index = listeners.findIndex(l => l.id === listenerId);
            if (index > -1) {
                listeners.splice(index, 1);
            }
        } else {
            // 移除所有监听器
            listeners.length = 0;
        }
        
        // 如果没有监听器了,删除事件
        if (listeners.length === 0) {
            this.events.delete(eventName);
        }
    }
    
    // 触发事件
    emit(eventName, ...args) {
        if (!this.events.has(eventName)) return false;
        
        const listeners = [...this.events.get(eventName)];
        let hasListeners = false;
        
        listeners.forEach(listener => {
            try {
                hasListeners = true;
                listener.callback.apply(listener.context, args);
            } catch (error) {
                console.error(`事件 "${eventName}" 监听器执行错误:`, error);
            }
        });
        
        return hasListeners;
    }
    
    // 异步触发事件
    async emitAsync(eventName, ...args) {
        if (!this.events.has(eventName)) return false;
        
        const listeners = [...this.events.get(eventName)];
        let hasListeners = false;
        
        for (const listener of listeners) {
            try {
                hasListeners = true;
                await listener.callback.apply(listener.context, args);
            } catch (error) {
                console.error(`异步事件 "${eventName}" 监听器执行错误:`, error);
            }
        }
        
        return hasListeners;
    }
    
    // 获取事件监听器数量
    listenerCount(eventName) {
        return this.events.has(eventName) ? this.events.get(eventName).length : 0;
    }
    
    // 获取所有事件名称
    eventNames() {
        return Array.from(this.events.keys());
    }
    
    // 设置最大监听器数量
    setMaxListeners(n) {
        this.maxListeners = n;
    }
    
    // 清除所有事件
    clear() {
        this.events.clear();
        this.onceEvents.clear();
    }
}

// 全局事件总线
const globalEventBus = new EventBus();

// 组件间通信混入
const CommunicationMixin = {
    // 发送消息给父组件
    $emit(eventName, data) {
        this.emit(`component:${eventName}`, {
            source: this,
            data
        });
    },
    
    // 发送消息给子组件
    $broadcast(eventName, data) {
        this.children.forEach(child => {
            if (typeof child.$receive === 'function') {
                child.$receive(eventName, data, this);
            }
        });
    },
    
    // 接收消息
    $receive(eventName, data, sender) {
        const handler = this[`on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`];
        if (typeof handler === 'function') {
            handler.call(this, data, sender);
        }
    },
    
    // 全局消息
    $publish(eventName, data) {
        globalEventBus.emit(eventName, {
            source: this,
            data
        });
    },
    
    $subscribe(eventName, callback) {
        return globalEventBus.on(eventName, callback, this);
    },
    
    $unsubscribe(eventName, listenerId) {
        globalEventBus.off(eventName, listenerId);
    }
};

5.3.2 Props 和 Slots 系统

class PropsManager {
    constructor(component, propDefinitions = {}) {
        this.component = component;
        this.definitions = propDefinitions;
        this.props = {};
        this.watchers = new Map();
    }
    
    // 定义 prop
    define(name, definition) {
        this.definitions[name] = this.normalizePropDefinition(definition);
    }
    
    // 标准化 prop 定义
    normalizePropDefinition(definition) {
        if (typeof definition === 'function') {
            return { type: definition };
        }
        
        if (Array.isArray(definition)) {
            return { type: definition };
        }
        
        return {
            type: definition.type || String,
            default: definition.default,
            required: definition.required || false,
            validator: definition.validator
        };
    }
    
    // 设置 props
    setProps(props) {
        Object.entries(props).forEach(([name, value]) => {
            this.setProp(name, value);
        });
    }
    
    // 设置单个 prop
    setProp(name, value) {
        const definition = this.definitions[name];
        if (!definition) {
            console.warn(`未定义的 prop: ${name}`);
            return;
        }
        
        // 类型检查
        if (!this.validateType(value, definition.type)) {
            console.error(`Prop "${name}" 类型错误`);
            return;
        }
        
        // 自定义验证
        if (definition.validator && !definition.validator(value)) {
            console.error(`Prop "${name}" 验证失败`);
            return;
        }
        
        const oldValue = this.props[name];
        this.props[name] = value;
        
        // 触发监听器
        this.notifyWatchers(name, value, oldValue);
    }
    
    // 获取 prop
    getProp(name) {
        if (this.props.hasOwnProperty(name)) {
            return this.props[name];
        }
        
        const definition = this.definitions[name];
        if (definition && definition.default !== undefined) {
            return typeof definition.default === 'function' ? 
                definition.default() : definition.default;
        }
        
        return undefined;
    }
    
    // 类型验证
    validateType(value, type) {
        if (Array.isArray(type)) {
            return type.some(t => this.validateSingleType(value, t));
        }
        return this.validateSingleType(value, type);
    }
    
    validateSingleType(value, type) {
        if (value === null || value === undefined) {
            return true;
        }
        
        switch (type) {
            case String:
                return typeof value === 'string';
            case Number:
                return typeof value === 'number' && !isNaN(value);
            case Boolean:
                return typeof value === 'boolean';
            case Array:
                return Array.isArray(value);
            case Object:
                return typeof value === 'object' && !Array.isArray(value);
            case Function:
                return typeof value === 'function';
            default:
                return value instanceof type;
        }
    }
    
    // 监听 prop 变化
    watch(name, callback) {
        if (!this.watchers.has(name)) {
            this.watchers.set(name, []);
        }
        this.watchers.get(name).push(callback);
    }
    
    // 通知监听器
    notifyWatchers(name, newValue, oldValue) {
        const callbacks = this.watchers.get(name) || [];
        callbacks.forEach(callback => {
            try {
                callback(newValue, oldValue);
            } catch (error) {
                console.error(`Prop "${name}" 监听器错误:`, error);
            }
        });
    }
    
    // 验证必需的 props
    validateRequired() {
        const missing = [];
        Object.entries(this.definitions).forEach(([name, definition]) => {
            if (definition.required && !this.props.hasOwnProperty(name)) {
                missing.push(name);
            }
        });
        
        if (missing.length > 0) {
            console.error(`缺少必需的 props: ${missing.join(', ')}`);
        }
        
        return missing.length === 0;
    }
}

// Slots 管理器
class SlotsManager {
    constructor(component) {
        this.component = component;
        this.slots = new Map();
        this.namedSlots = new Map();
    }
    
    // 注册插槽
    registerSlot(name, element) {
        this.namedSlots.set(name, element);
    }
    
    // 设置插槽内容
    setSlotContent(name, content) {
        const slot = this.namedSlots.get(name);
        if (!slot) {
            console.warn(`插槽 "${name}" 不存在`);
            return;
        }
        
        if (typeof content === 'string') {
            slot.innerHTML = content;
        } else if (content instanceof Element) {
            slot.innerHTML = '';
            slot.appendChild(content);
        } else if (Array.isArray(content)) {
            slot.innerHTML = '';
            content.forEach(item => {
                if (typeof item === 'string') {
                    slot.insertAdjacentHTML('beforeend', item);
                } else if (item instanceof Element) {
                    slot.appendChild(item);
                }
            });
        }
    }
    
    // 获取插槽内容
    getSlotContent(name) {
        const slot = this.namedSlots.get(name);
        return slot ? slot.innerHTML : '';
    }
    
    // 检查插槽是否有内容
    hasSlotContent(name) {
        const slot = this.namedSlots.get(name);
        return slot && slot.children.length > 0;
    }
    
    // 清空插槽
    clearSlot(name) {
        const slot = this.namedSlots.get(name);
        if (slot) {
            slot.innerHTML = '';
        }
    }
    
    // 自动发现插槽
    discoverSlots() {
        const slots = this.component.element.querySelectorAll('[data-slot]');
        slots.forEach(slot => {
            const name = slot.dataset.slot;
            this.registerSlot(name, slot);
        });
    }
}

// 带 Props 和 Slots 的组件
class PropsComponent extends StatefulComponent {
    constructor(element, options = {}) {
        super(element, options);
        
        this.propsManager = new PropsManager(this, this.getPropDefinitions());
        this.slotsManager = new SlotsManager(this);
        
        this.setupProps();
        this.setupSlots();
    }
    
    getPropDefinitions() {
        return {};
    }
    
    setupProps() {
        // 从 data 属性解析 props
        const props = this.parsePropsFromAttributes();
        this.propsManager.setProps(props);
        
        // 验证必需的 props
        this.propsManager.validateRequired();
        
        // 监听 props 变化
        Object.keys(this.getPropDefinitions()).forEach(name => {
            this.propsManager.watch(name, (newValue, oldValue) => {
                this.onPropChanged(name, newValue, oldValue);
            });
        });
    }
    
    setupSlots() {
        this.slotsManager.discoverSlots();
    }
    
    parsePropsFromAttributes() {
        const props = {};
        Array.from(this.element.attributes).forEach(attr => {
            if (attr.name.startsWith('data-prop-')) {
                const propName = attr.name.substring(10).replace(/-([a-z])/g, (g) => g[1].toUpperCase());
                let value = attr.value;
                
                try {
                    value = JSON.parse(value);
                } catch (e) {
                    // 保持字符串值
                }
                
                props[propName] = value;
            }
        });
        return props;
    }
    
    onPropChanged(name, newValue, oldValue) {
        // 子类可以重写此方法来响应 prop 变化
        this.render();
    }
    
    // 获取 prop 值
    $prop(name) {
        return this.propsManager.getProp(name);
    }
    
    // 设置插槽内容
    $slot(name, content) {
        this.slotsManager.setSlotContent(name, content);
    }
    
    // 检查插槽
    $hasSlot(name) {
        return this.slotsManager.hasSlotContent(name);
    }
}

5.4 模块化开发模式

5.4.1 模块系统

// 模块管理器
class ModuleManager {
    constructor() {
        this.modules = new Map();
        this.dependencies = new Map();
        this.loadedModules = new Set();
        this.loadingModules = new Set();
    }
    
    // 定义模块
    define(name, dependencies, factory) {
        if (typeof dependencies === 'function') {
            factory = dependencies;
            dependencies = [];
        }
        
        this.modules.set(name, {
            dependencies,
            factory,
            exports: null
        });
        
        this.dependencies.set(name, dependencies);
        
        // 尝试加载模块
        this.tryLoadModule(name);
    }
    
    // 加载模块
    async load(name) {
        if (this.loadedModules.has(name)) {
            return this.modules.get(name).exports;
        }
        
        if (this.loadingModules.has(name)) {
            // 等待模块加载完成
            return new Promise((resolve) => {
                const checkLoaded = () => {
                    if (this.loadedModules.has(name)) {
                        resolve(this.modules.get(name).exports);
                    } else {
                        setTimeout(checkLoaded, 10);
                    }
                };
                checkLoaded();
            });
        }
        
        return this.loadModule(name);
    }
    
    // 加载模块实现
    async loadModule(name) {
        const moduleInfo = this.modules.get(name);
        if (!moduleInfo) {
            throw new Error(`模块 "${name}" 未定义`);
        }
        
        this.loadingModules.add(name);
        
        try {
            // 加载依赖
            const dependencies = await Promise.all(
                moduleInfo.dependencies.map(dep => this.load(dep))
            );
            
            // 执行工厂函数
            const exports = moduleInfo.factory(...dependencies);
            moduleInfo.exports = exports;
            
            this.loadedModules.add(name);
            this.loadingModules.delete(name);
            
            return exports;
        } catch (error) {
            this.loadingModules.delete(name);
            throw error;
        }
    }
    
    // 尝试加载模块
    tryLoadModule(name) {
        const dependencies = this.dependencies.get(name) || [];
        const canLoad = dependencies.every(dep => this.loadedModules.has(dep));
        
        if (canLoad && !this.loadedModules.has(name) && !this.loadingModules.has(name)) {
            this.loadModule(name).catch(error => {
                console.error(`模块 "${name}" 加载失败:`, error);
            });
        }
    }
    
    // 获取模块依赖图
    getDependencyGraph() {
        const graph = {};
        this.dependencies.forEach((deps, name) => {
            graph[name] = deps;
        });
        return graph;
    }
    
    // 检查循环依赖
    checkCircularDependencies() {
        const visited = new Set();
        const visiting = new Set();
        const cycles = [];
        
        const visit = (name, path = []) => {
            if (visiting.has(name)) {
                const cycleStart = path.indexOf(name);
                cycles.push(path.slice(cycleStart).concat(name));
                return;
            }
            
            if (visited.has(name)) return;
            
            visiting.add(name);
            const deps = this.dependencies.get(name) || [];
            
            deps.forEach(dep => {
                visit(dep, path.concat(name));
            });
            
            visiting.delete(name);
            visited.add(name);
        };
        
        this.dependencies.forEach((_, name) => {
            if (!visited.has(name)) {
                visit(name);
            }
        });
        
        return cycles;
    }
}

// 全局模块管理器
const moduleManager = new ModuleManager();

// 便捷函数
function define(name, dependencies, factory) {
    moduleManager.define(name, dependencies, factory);
}

function require(name) {
    return moduleManager.load(name);
}

// 使用示例

// 定义工具模块
define('utils', [], function() {
    return {
        debounce(func, wait) {
            let timeout;
            return function executedFunction(...args) {
                const later = () => {
                    clearTimeout(timeout);
                    func(...args);
                };
                clearTimeout(timeout);
                timeout = setTimeout(later, wait);
            };
        },
        
        throttle(func, limit) {
            let inThrottle;
            return function() {
                const args = arguments;
                const context = this;
                if (!inThrottle) {
                    func.apply(context, args);
                    inThrottle = true;
                    setTimeout(() => inThrottle = false, limit);
                }
            };
        },
        
        deepClone(obj) {
            if (obj === null || typeof obj !== 'object') return obj;
            if (obj instanceof Date) return new Date(obj.getTime());
            if (obj instanceof Array) return obj.map(item => this.deepClone(item));
            if (typeof obj === 'object') {
                const clonedObj = {};
                for (const key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        clonedObj[key] = this.deepClone(obj[key]);
                    }
                }
                return clonedObj;
            }
        }
    };
});

// 定义 HTTP 模块
define('http', ['utils'], function(utils) {
    class HttpClient {
        constructor(baseURL = '') {
            this.baseURL = baseURL;
            this.interceptors = {
                request: [],
                response: []
            };
        }
        
        async request(config) {
            // 应用请求拦截器
            for (const interceptor of this.interceptors.request) {
                config = await interceptor(config);
            }
            
            const url = this.baseURL + config.url;
            const options = {
                method: config.method || 'GET',
                headers: config.headers || {},
                body: config.data ? JSON.stringify(config.data) : undefined
            };
            
            if (config.data && options.method !== 'GET') {
                options.headers['Content-Type'] = 'application/json';
            }
            
            try {
                const response = await fetch(url, options);
                let result = {
                    data: await response.json(),
                    status: response.status,
                    statusText: response.statusText,
                    headers: response.headers
                };
                
                // 应用响应拦截器
                for (const interceptor of this.interceptors.response) {
                    result = await interceptor(result);
                }
                
                return result;
            } catch (error) {
                throw new Error(`HTTP 请求失败: ${error.message}`);
            }
        }
        
        get(url, config = {}) {
            return this.request({ ...config, method: 'GET', url });
        }
        
        post(url, data, config = {}) {
            return this.request({ ...config, method: 'POST', url, data });
        }
        
        put(url, data, config = {}) {
            return this.request({ ...config, method: 'PUT', url, data });
        }
        
        delete(url, config = {}) {
            return this.request({ ...config, method: 'DELETE', url });
        }
    }
    
    return {
        HttpClient,
        create: (config) => new HttpClient(config.baseURL)
    };
});

// 定义组件模块
define('components/modal', ['utils'], function(utils) {
    class Modal extends PropsComponent {
        getPropDefinitions() {
            return {
                title: { type: String, default: '' },
                visible: { type: Boolean, default: false },
                closable: { type: Boolean, default: true },
                maskClosable: { type: Boolean, default: true },
                width: { type: [String, Number], default: '520px' },
                zIndex: { type: Number, default: 1000 }
            };
        }
        
        getTemplate() {
            return `
                <div class="modal-mask" style="display: none;">
                    <div class="modal-wrapper">
                        <div class="modal-container">
                            <div class="modal-header">
                                <div class="modal-title" data-slot="title"></div>
                                <button class="modal-close" v-if="closable">×</button>
                            </div>
                            <div class="modal-body" data-slot="default"></div>
                            <div class="modal-footer" data-slot="footer"></div>
                        </div>
                    </div>
                </div>
            `;
        }
        
        getEvents() {
            return {
                '.modal-close': {
                    'click': this.close
                },
                '.modal-mask': {
                    'click': this.handleMaskClick
                }
            };
        }
        
        onPropChanged(name, newValue, oldValue) {
            if (name === 'visible') {
                if (newValue) {
                    this.show();
                } else {
                    this.hide();
                }
            }
        }
        
        show() {
            const mask = this.$('.modal-mask');
            mask.style.display = 'flex';
            mask.style.zIndex = this.$prop('zIndex');
            
            const container = this.$('.modal-container');
            container.style.width = this.$prop('width');
            
            // 设置标题
            if (this.$prop('title')) {
                this.$slot('title', this.$prop('title'));
            }
            
            this.$emit('show');
        }
        
        hide() {
            const mask = this.$('.modal-mask');
            mask.style.display = 'none';
            this.$emit('hide');
        }
        
        close() {
            if (this.$prop('closable')) {
                this.hide();
                this.$emit('close');
            }
        }
        
        handleMaskClick(event) {
            if (event.target === event.currentTarget && this.$prop('maskClosable')) {
                this.close();
            }
        }
    }
    
    return Modal;
});

5.4.2 插件系统

class PluginManager {
    constructor() {
        this.plugins = new Map();
        this.hooks = new Map();
        this.installedPlugins = new Set();
    }
    
    // 注册插件
    register(name, plugin) {
        if (this.plugins.has(name)) {
            console.warn(`插件 "${name}" 已存在`);
            return;
        }
        
        this.plugins.set(name, plugin);
    }
    
    // 安装插件
    install(name, options = {}) {
        if (this.installedPlugins.has(name)) {
            console.warn(`插件 "${name}" 已安装`);
            return;
        }
        
        const plugin = this.plugins.get(name);
        if (!plugin) {
            throw new Error(`插件 "${name}" 不存在`);
        }
        
        // 检查依赖
        if (plugin.dependencies) {
            plugin.dependencies.forEach(dep => {
                if (!this.installedPlugins.has(dep)) {
                    throw new Error(`插件 "${name}" 依赖 "${dep}",但 "${dep}" 未安装`);
                }
            });
        }
        
        // 安装插件
        if (typeof plugin.install === 'function') {
            plugin.install(this, options);
        }
        
        this.installedPlugins.add(name);
        
        // 触发安装钩子
        this.executeHook('plugin:installed', { name, plugin, options });
    }
    
    // 卸载插件
    uninstall(name) {
        if (!this.installedPlugins.has(name)) {
            console.warn(`插件 "${name}" 未安装`);
            return;
        }
        
        const plugin = this.plugins.get(name);
        
        // 检查是否有其他插件依赖此插件
        const dependents = [];
        this.plugins.forEach((p, n) => {
            if (p.dependencies && p.dependencies.includes(name) && this.installedPlugins.has(n)) {
                dependents.push(n);
            }
        });
        
        if (dependents.length > 0) {
            throw new Error(`无法卸载插件 "${name}",以下插件依赖它: ${dependents.join(', ')}`);
        }
        
        // 卸载插件
        if (typeof plugin.uninstall === 'function') {
            plugin.uninstall(this);
        }
        
        this.installedPlugins.delete(name);
        
        // 触发卸载钩子
        this.executeHook('plugin:uninstalled', { name, plugin });
    }
    
    // 注册钩子
    addHook(hookName, callback) {
        if (!this.hooks.has(hookName)) {
            this.hooks.set(hookName, []);
        }
        this.hooks.get(hookName).push(callback);
    }
    
    // 执行钩子
    executeHook(hookName, data) {
        const callbacks = this.hooks.get(hookName) || [];
        callbacks.forEach(callback => {
            try {
                callback(data);
            } catch (error) {
                console.error(`钩子 "${hookName}" 执行错误:`, error);
            }
        });
    }
    
    // 获取已安装的插件列表
    getInstalledPlugins() {
        return Array.from(this.installedPlugins);
    }
    
    // 获取插件信息
    getPluginInfo(name) {
        const plugin = this.plugins.get(name);
        return plugin ? {
            name,
            version: plugin.version || '1.0.0',
            description: plugin.description || '',
            dependencies: plugin.dependencies || [],
            installed: this.installedPlugins.has(name)
        } : null;
    }
}

// 全局插件管理器
const pluginManager = new PluginManager();

// 示例插件:表单验证
const FormValidationPlugin = {
    name: 'form-validation',
    version: '1.0.0',
    description: '表单验证插件',
    dependencies: ['utils'],
    
    install(pluginManager, options = {}) {
        // 扩展组件基类
        const originalSetupEvents = Component.prototype.setupEvents;
        Component.prototype.setupEvents = function() {
            originalSetupEvents.call(this);
            
            // 自动设置表单验证
            if (this.element.tagName === 'FORM') {
                this.setupFormValidation();
            }
        };
        
        Component.prototype.setupFormValidation = function() {
            this.validators = new Map();
            this.validationRules = {};
            
            // 添加验证方法
            this.addValidator = function(field, rules) {
                this.validationRules[field] = rules;
            };
            
            this.validate = function() {
                const errors = {};
                let isValid = true;
                
                Object.entries(this.validationRules).forEach(([field, rules]) => {
                    const element = this.$(field);
                    if (!element) return;
                    
                    const value = element.value;
                    const fieldErrors = [];
                    
                    rules.forEach(rule => {
                        if (!rule.validator(value)) {
                            fieldErrors.push(rule.message);
                            isValid = false;
                        }
                    });
                    
                    if (fieldErrors.length > 0) {
                        errors[field] = fieldErrors;
                    }
                });
                
                return { isValid, errors };
            };
        };
        
        console.log('表单验证插件已安装');
    },
    
    uninstall(pluginManager) {
        // 清理扩展
        delete Component.prototype.setupFormValidation;
        delete Component.prototype.addValidator;
        delete Component.prototype.validate;
        
        console.log('表单验证插件已卸载');
    }
};

// 注册和安装插件
pluginsManager.register('form-validation', FormValidationPlugin);
pluginsManager.install('form-validation');

5.5 实践练习

5.5.1 创建一个完整的 Todo 应用组件

// Todo 项组件
class TodoItem extends PropsComponent {
    getPropDefinitions() {
        return {
            todo: {
                type: Object,
                required: true,
                validator: (value) => {
                    return value && typeof value.id !== 'undefined' && 
                           typeof value.text === 'string' && 
                           typeof value.completed === 'boolean';
                }
            },
            editable: { type: Boolean, default: true },
            deletable: { type: Boolean, default: true }
        };
    }
    
    getInitialState() {
        return {
            editing: false,
            editText: ''
        };
    }
    
    getTemplate() {
        const todo = this.$prop('todo');
        return `
            <div class="todo-item ${todo.completed ? 'completed' : ''}">
                <div class="todo-content">
                    <input type="checkbox" class="todo-checkbox" 
                           ${todo.completed ? 'checked' : ''}>
                    <span class="todo-text" style="display: ${this.state.editing ? 'none' : 'block'}">
                        ${todo.text}
                    </span>
                    <input type="text" class="todo-edit" 
                           style="display: ${this.state.editing ? 'block' : 'none'}" 
                           value="${todo.text}">
                </div>
                <div class="todo-actions">
                    ${this.$prop('editable') ? '<button class="btn-edit">编辑</button>' : ''}
                    ${this.$prop('deletable') ? '<button class="btn-delete">删除</button>' : ''}
                </div>
            </div>
        `;
    }
    
    getEvents() {
        return {
            '.todo-checkbox': {
                'change': this.handleToggle
            },
            '.btn-edit': {
                'click': this.handleEdit
            },
            '.btn-delete': {
                'click': this.handleDelete
            },
            '.todo-edit': {
                'blur': this.handleSave,
                'keydown': this.handleKeyDown
            },
            '.todo-text': {
                'dblclick': this.handleEdit
            }
        };
    }
    
    handleToggle(event) {
        const completed = event.target.checked;
        this.$emit('toggle', {
            id: this.$prop('todo').id,
            completed
        });
    }
    
    handleEdit() {
        if (!this.$prop('editable')) return;
        
        this.setState({
            editing: true,
            editText: this.$prop('todo').text
        });
        
        // 聚焦到编辑框
        setTimeout(() => {
            const editInput = this.$('.todo-edit');
            editInput.focus();
            editInput.select();
        }, 0);
    }
    
    handleSave() {
        const editText = this.$('.todo-edit').value.trim();
        
        if (editText && editText !== this.$prop('todo').text) {
            this.$emit('update', {
                id: this.$prop('todo').id,
                text: editText
            });
        }
        
        this.setState({ editing: false });
    }
    
    handleKeyDown(event) {
        if (event.key === 'Enter') {
            this.handleSave();
        } else if (event.key === 'Escape') {
            this.setState({ editing: false });
        }
    }
    
    handleDelete() {
        if (!this.$prop('deletable')) return;
        
        this.$emit('delete', {
            id: this.$prop('todo').id
        });
    }
}

// Todo 列表组件
class TodoList extends StatefulComponent {
    getInitialState() {
        return {
            todos: [],
            filter: 'all', // all, active, completed
            newTodoText: ''
        };
    }
    
    setupMutations() {
        this.stateManager.registerMutation('ADD_TODO', (state, todo) => {
            state.todos.push({
                id: Date.now(),
                text: todo.text,
                completed: false,
                createdAt: new Date()
            });
        });
        
        this.stateManager.registerMutation('TOGGLE_TODO', (state, { id, completed }) => {
            const todo = state.todos.find(t => t.id === id);
            if (todo) {
                todo.completed = completed;
            }
        });
        
        this.stateManager.registerMutation('UPDATE_TODO', (state, { id, text }) => {
            const todo = state.todos.find(t => t.id === id);
            if (todo) {
                todo.text = text;
            }
        });
        
        this.stateManager.registerMutation('DELETE_TODO', (state, { id }) => {
            const index = state.todos.findIndex(t => t.id === id);
            if (index > -1) {
                state.todos.splice(index, 1);
            }
        });
        
        this.stateManager.registerMutation('SET_FILTER', (state, filter) => {
            state.filter = filter;
        });
        
        this.stateManager.registerMutation('CLEAR_COMPLETED', (state) => {
            state.todos = state.todos.filter(todo => !todo.completed);
        });
    }
    
    setupComputed() {
        this.computed('filteredTodos', (state) => {
            switch (state.filter) {
                case 'active':
                    return state.todos.filter(todo => !todo.completed);
                case 'completed':
                    return state.todos.filter(todo => todo.completed);
                default:
                    return state.todos;
            }
        }, ['todos', 'filter']);
        
        this.computed('todoStats', (state) => {
            const total = state.todos.length;
            const completed = state.todos.filter(todo => todo.completed).length;
            const active = total - completed;
            
            return { total, completed, active };
        }, ['todos']);
    }
    
    getTemplate() {
        return `
            <div class="todo-app">
                <header class="todo-header">
                    <h1>Todo List</h1>
                    <div class="todo-input-container">
                        <input type="text" class="todo-input" 
                               placeholder="添加新任务..." 
                               value="${this.state.newTodoText}">
                        <button class="btn-add">添加</button>
                    </div>
                </header>
                
                <div class="todo-filters">
                    <button class="filter-btn ${this.state.filter === 'all' ? 'active' : ''}" 
                            data-filter="all">全部</button>
                    <button class="filter-btn ${this.state.filter === 'active' ? 'active' : ''}" 
                            data-filter="active">未完成</button>
                    <button class="filter-btn ${this.state.filter === 'completed' ? 'active' : ''}" 
                            data-filter="completed">已完成</button>
                </div>
                
                <div class="todo-list-container">
                    <!-- Todo 项将在这里动态渲染 -->
                </div>
                
                <footer class="todo-footer">
                    <div class="todo-stats">
                        <span>总计: ${this.getComputed('todoStats').total}</span>
                        <span>未完成: ${this.getComputed('todoStats').active}</span>
                        <span>已完成: ${this.getComputed('todoStats').completed}</span>
                    </div>
                    <button class="btn-clear-completed">清除已完成</button>
                </footer>
            </div>
        `;
    }
    
    getEvents() {
        return {
            '.todo-input': {
                'input': this.handleInputChange,
                'keydown': this.handleInputKeyDown
            },
            '.btn-add': {
                'click': this.handleAddTodo
            },
            '.filter-btn': {
                'click': this.handleFilterChange
            },
            '.btn-clear-completed': {
                'click': this.handleClearCompleted
            }
        };
    }
    
    updateDOM() {
        super.updateDOM();
        this.renderTodoItems();
    }
    
    renderTodoItems() {
        const container = this.$('.todo-list-container');
        container.innerHTML = '';
        
        const filteredTodos = this.getComputed('filteredTodos');
        
        filteredTodos.forEach(todo => {
            const itemElement = document.createElement('div');
            container.appendChild(itemElement);
            
            const todoItem = new TodoItem(itemElement, {
                todo: todo
            });
            
            // 监听 Todo 项事件
            todoItem.on('toggle', (event) => {
                this.commit('TOGGLE_TODO', event.detail.data);
            });
            
            todoItem.on('update', (event) => {
                this.commit('UPDATE_TODO', event.detail.data);
            });
            
            todoItem.on('delete', (event) => {
                this.commit('DELETE_TODO', event.detail.data);
            });
            
            this.addChild(`todo-${todo.id}`, todoItem);
        });
    }
    
    handleInputChange(event) {
        this.setState('newTodoText', event.target.value);
    }
    
    handleInputKeyDown(event) {
        if (event.key === 'Enter') {
            this.handleAddTodo();
        }
    }
    
    handleAddTodo() {
        const text = this.state.newTodoText.trim();
        if (text) {
            this.commit('ADD_TODO', { text });
            this.setState('newTodoText', '');
            this.$('.todo-input').value = '';
        }
    }
    
    handleFilterChange(event) {
        const filter = event.target.dataset.filter;
        this.commit('SET_FILTER', filter);
    }
    
    handleClearCompleted() {
        this.commit('CLEAR_COMPLETED');
    }
}

// 注册组件
componentFactory.register('todo-item', TodoItem);
componentFactory.register('todo-list', TodoList);

5.6 本章小结

5.6.1 核心概念

  • 组件架构:基于类的组件系统,支持生命周期和状态管理
  • 模块化:AMD 风格的模块定义和依赖管理
  • 组件通信:Props、Events、Slots 和全局事件总线
  • 插件系统:可扩展的插件架构

5.6.2 技术要点

  1. 生命周期管理:完整的组件生命周期钩子
  2. 状态管理:响应式状态系统和计算属性
  3. 组件通信:多种通信方式的组合使用
  4. 模块化开发:依赖注入和模块加载

5.6.3 最佳实践

  • 遵循单一职责原则设计组件
  • 使用 Props 进行父子组件通信
  • 合理使用事件总线避免过度耦合
  • 模块化组织代码提高可维护性

5.6.4 下一章预告

下一章将学习 数据绑定与状态管理,包括: - 双向数据绑定实现 - 全局状态管理 - 数据流管理模式 - 状态持久化

通过本章的学习,你已经掌握了完整的组件开发和模块化技能,能够构建复杂的应用程序架构。