原生js实现组件化
原生 JavaScript 实现组件化的方法
使用自定义元素(Custom Elements)
通过 customElements.define 定义自定义元素,继承 HTMLElement 类。组件可以封装模板、样式和行为。
class MyComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
.component { color: red; }
</style>
<div class="component">Hello World</div>
`;
}
}
customElements.define('my-component', MyComponent);
基于类的封装
通过 ES6 类封装组件逻辑,结合 DOM 操作实现渲染和更新。类的实例管理组件状态和生命周期。
class Counter {
constructor(selector) {
this.count = 0;
this.element = document.querySelector(selector);
this.render();
this.element.addEventListener('click', () => this.increment());
}
increment() {
this.count++;
this.render();
}
render() {
this.element.innerHTML = `Count: ${this.count}`;
}
}
new Counter('#counter');
模板与插槽
使用 <template> 和 <slot> 分离 HTML 结构与动态内容。模板定义组件骨架,插槽填充可变部分。

<template id="user-card">
<div class="card">
<slot name="name">Default Name</slot>
<slot name="email"></slot>
</div>
</template>
<script>
const template = document.getElementById('user-card');
const card = template.content.cloneNode(true);
document.body.appendChild(card);
</script>
事件委托与通信
通过自定义事件或回调函数实现组件间通信。父组件监听子组件事件并处理数据交换。
class ChildComponent extends HTMLElement {
fireEvent() {
this.dispatchEvent(new CustomEvent('child-event', { detail: { data: 123 } }));
}
}
document.querySelector('child-component')
.addEventListener('child-event', e => console.log(e.detail.data));
状态管理
利用 Proxy 或 Object.defineProperty 监听状态变化,自动触发视图更新。

const state = new Proxy({ value: 0 }, {
set(target, key, value) {
target[key] = value;
document.getElementById('app').textContent = value;
return true;
}
});
state.value = 1; // 自动更新DOM
生命周期钩子
在自定义元素中实现 connectedCallback、disconnectedCallback 等方法,管理组件的挂载与卸载逻辑。
class LifecycleComponent extends HTMLElement {
connectedCallback() {
console.log('Component mounted');
}
disconnectedCallback() {
console.log('Component removed');
}
}
动态加载组件
通过 fetch 或 import() 动态加载组件资源,实现按需加载。
const loadComponent = async (name) => {
const { default: Component } = await import(`./components/${name}.js`);
customElements.define(name, Component);
};
loadComponent('dynamic-component');
注意事项
- 样式隔离:使用 Shadow DOM 避免全局样式污染。
- 性能优化:避免频繁 DOM 操作,必要时使用
requestAnimationFrame或虚拟 DOM 简化更新。 - 浏览器兼容性:自定义元素需 polyfill(如
@webcomponents/webcomponentsjs)支持旧版浏览器。






