• 初步认识 Web Components 并实现一个按钮


    目录

    1.Web Components 基本概念

    1.1 三个场景

    1.2 是什么

    2.使用 Custom Elements 实现一个按钮

    2.1 概念介绍

    2.1.1 Shadow DOM

    2.1.2 Element.attachShadow()

    2.1.3 在组件中 使用 Shadow DOM 基本步骤

    2.1.4 attributeChangedCallback

    2.1.5 get observedAttributes

    2.1.6 dispatchEvent()

    2.1.7 CustomEvent

    2.2 实践出真知

    2.2.1 初步实现按钮

    2.2.2 给按钮加属性-传递

    2.2.3 给按钮加属性-映射

    2.2.4 给按钮加事件-普通事件

    2.2.5 给按钮加事件-自定义事件


    通过这篇文章,你可以学习到:

    • 如何使用原生 JavaScript 构建一个 Web Component
    • 如何在应用程序中使用 Web Component

    1.Web Components 基本概念

    1.1 三个场景

    • Vue2 升级到 Vue3 后,饿了么官方组件库也被迫从 ElementUI 升级到 ElementPlus,聪明的你不禁会发出疑问:难道每次框架升级都需要升级组件库吗?
    • xx项目,参考了个 React 开源项目,但开源项目组件用 React 写的,而我得用 Vue 开发
    • xx项目,作为总集公司,其他厂商需要使用总集提供的组件库,他们不得不投入时间成本学习 Vue3,老板因此很生气

    针对上面的场景,预言家 Google 早在2011年就推出了解决方案 —— Web Component

    1.2 是什么

    Web Components 也被叫做 Custom Elements,它已经成为 浏览器标准 API

    下面是各大浏览器针对 Web Components(Custom Elements) 的支持情况:

    Custom Elements (V1) | Can I use... Support tables for HTML5, CSS3, etcicon-default.png?t=N7T8https://caniuse.com/custom-elementsv1

    开发者可以在 Custom Elements 中,封装结构(HTML)、样式(CSS)和行为(JavaScript),最终生成自定义元素标签(使用方式类似于原生 html 标签),不会受框架限制

    举个例子:

    1. <button name="button">按钮button>
    2. <el-button type="success">按钮el-button>
    3. <my-button text="按钮">my-button>

    2.使用 Custom Elements 实现一个按钮

    2.1 概念介绍

    温馨提示:也可以食用完下面的实践出真知,再回头阅读这儿的概念介绍,这样更容易理解

    2.1.1 Shadow DOM

    一种将 DOM、样式、行为 封装在一个可重用的、封装的组件中的技术

    Shadow DOM 可以帮助开发者避免样式和 DOM 冲突,提高代码的可维护性和可重用性(大家可以回忆一下修改 Ionic 组件样式时的那种感觉)

    它允许开发者创建自定义元素,这些元素可以在页面上使用,就像普通的 HTML 元素一样

    我们看下 Ionic 官网按钮示例,可以看出 ionic 组件就是用 Shadow DOM 写的自定义元素

    2.1.2 Element.attachShadow()

    该方法返回 ShadowRoot 对象,用于将一个 Shadow DOM 附加到 指定元素 上

    1. // 通过 Element.attachShadow() 获取 ShadowRoot 对象
    2. // open shadow root:元素可以从 js 外部访问根节点
    3. // closed 拒绝从 js 外部访问关闭的 shadow root 节点
    4. const shadowRoot = this.attachShadow({ mode: "open" });
    5. // 把 Shadow DOM 附加到 template 上
    6. shadowRoot.appendChild(templateDOM.content.cloneNode(true));

    关于操作 shadow root 节点的必要性:这个当然很重要了

    比如修改 Shadow Dom 中某个节点的 innerHTML

    1. constructor() {
    2. // ...
    3. // 获取按钮文字 DOM
    4. this.btnTextDOM = shadowRoot.querySelector(".button-inner");
    5. }
    6. render() {
    7. this.btnTextDOM.innerHTML = this.text;
    8. }

    2.1.3 在组件中 使用 Shadow DOM 基本步骤

    总体思路:创建组件模板,给组件加 Shadow DOM

    具体步骤:

    1. 创建一个