当前位置:首页 > JavaScript

原生js实现组件化

2026-03-01 16:27:31JavaScript

原生 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));

状态管理

利用 ProxyObject.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

生命周期钩子

在自定义元素中实现 connectedCallbackdisconnectedCallback 等方法,管理组件的挂载与卸载逻辑。

class LifecycleComponent extends HTMLElement {
  connectedCallback() {
    console.log('Component mounted');
  }
  disconnectedCallback() {
    console.log('Component removed');
  }
}

动态加载组件

通过 fetchimport() 动态加载组件资源,实现按需加载。

原生js实现组件化

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)支持旧版浏览器。

标签: 组件js
分享给朋友:

相关文章

jquery.js

jquery.js

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,用于简化 HTML 文档遍历、事件处理、动画设计和 Ajax 交互。它的设计宗旨是“Write Less, Do Mor…

vue radio组件实现

vue radio组件实现

Vue Radio 组件实现 在 Vue 中实现 Radio 组件可以通过原生 HTML 的 <input type="radio"> 结合 Vue 的响应式特性,或者使用第三方 UI 库…

vue实现拖拽实现组件嵌套

vue实现拖拽实现组件嵌套

实现拖拽组件嵌套的核心思路 Vue中实现拖拽组件嵌套需要结合拖拽库(如vuedraggable)和组件递归渲染。核心在于动态管理嵌套数据结构,并通过事件传递实现层级更新。 安装必要依赖 推荐使用vu…

js实现变形

js实现变形

使用 CSS 和 JavaScript 实现元素变形 在 JavaScript 中实现变形效果通常结合 CSS 的 transform 属性,通过动态修改该属性实现元素的旋转、缩放、倾斜或平移。 基…

js实现防洪

js实现防洪

防抖(Debounce)实现 防抖的核心思想是在事件触发后延迟执行回调函数,若在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口调整等场景。 function debounce(func,…

如何缓存react组件

如何缓存react组件

缓存React组件的方法 React.memo 使用React.memo对函数组件进行浅比较缓存,避免不必要的重新渲染。适用于props不变的场景。 const MemoizedComponen…