原生js实现组件化
原生 JavaScript 实现组件化
原生 JavaScript 可以通过多种方式实现组件化,以下是几种常见的方法:
使用类和模块化
通过 ES6 的类和模块化语法,可以将组件封装为独立的模块。每个组件可以是一个类,包含自己的状态和方法。
class ButtonComponent {
constructor(text) {
this.text = text;
this.element = document.createElement('button');
this.element.textContent = this.text;
this.element.addEventListener('click', this.handleClick.bind(this));
}
handleClick() {
console.log('Button clicked:', this.text);
}
render() {
return this.element;
}
}
// 使用组件
const button = new ButtonComponent('Click me');
document.body.appendChild(button.render());
使用自定义元素(Web Components)
Web Components 是一组浏览器原生支持的 API,允许创建可重用的自定义元素。
class MyComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
button {
background: blue;
color: white;
}
</style>
<button><slot></slot></button>
`;
}
}
// 注册自定义元素
customElements.define('my-button', MyComponent);
// 使用组件
document.body.innerHTML = '<my-button>Click me</my-button>';
使用事件委托和动态渲染
通过事件委托和动态渲染,可以将组件的行为和渲染逻辑分离。
const Component = {
data: { count: 0 },
template: `
<div>
<button id="increment">Increment</button>
<span id="count">${this.data.count}</span>
</div>
`,
render() {
const container = document.createElement('div');
container.innerHTML = this.template;
container.addEventListener('click', (e) => {
if (e.target.id === 'increment') {
this.data.count++;
container.querySelector('#count').textContent = this.data.count;
}
});
return container;
}
};
// 使用组件
document.body.appendChild(Component.render());
使用工厂函数
通过工厂函数创建组件实例,可以灵活地生成多个组件实例。
function createComponent(config) {
const element = document.createElement(config.tag || 'div');
element.textContent = config.text || '';
if (config.className) {
element.className = config.className;
}
if (config.onClick) {
element.addEventListener('click', config.onClick);
}
return element;
}
// 使用组件
const button = createComponent({
tag: 'button',
text: 'Click me',
className: 'btn',
onClick: () => console.log('Button clicked')
});
document.body.appendChild(button);
使用闭包封装状态
通过闭包封装组件的状态和方法,可以实现私有变量和公共接口的分离。
function CounterComponent() {
let count = 0;
const element = document.createElement('div');
const button = document.createElement('button');
button.textContent = 'Increment';
const display = document.createElement('span');
display.textContent = count;
button.addEventListener('click', () => {
count++;
display.textContent = count;
});
element.appendChild(button);
element.appendChild(display);
return {
element,
getCount: () => count
};
}
// 使用组件
const counter = CounterComponent();
document.body.appendChild(counter.element);
以上方法展示了如何使用原生 JavaScript 实现组件化,每种方法适用于不同的场景和需求。







