• Web:体验原生的组件化开发


    什么是组件化

    狭义的组件化一般是指标签化,也就是以自定义标签为核心的机制。
    广义的组件化包括对数据逻辑层业务梳理,形成不同层级的能力封装

    在前端技术的发展潮流下,可大致分为三个阶段:

    • web1.0

    1.0阶段,技术实现主要以原生html、css、javascript。前端工程师概念稀薄,编程思想主要是以函数为单位分离行为,每个函数做一件事

    • web2.0

    到了2.0时代,jQuery、Bootstrap等模板引擎库开始出现。编程上出现了模块化规范,以模块为单位,每个模块做一件事

    • web3.0(此web3.0非彼web3.0)

    3.0阶段是前端技术最活跃的时期,angular、react、vue相继登场。用户对产品的体验越来越高,项目上的业务、交互越来越复杂,技术上前后端开始分离。编程思想开始以组件为单位,每个组件拥有独立的结构、视图和行为,代表一个完整的个体

    在这个时期,关于组件化的开发模式愈演愈烈,各个框架和库都有自己的标准,这对于项目间的兼容并不友好。于是,W3C早期提出的 Web Components 概念逐渐受到关注。

    Web Components

    Web Components是W3C定义的标准,是一套原生的组件化开发技术,它允许你创建可重用的定制元素并在web应用中使用它们。

    使用Web Components不需要借助任何第三方框架或库,可用于开发跨端、跨框架的组件库

    使用Web Components

    自定义元素

    Web Components 标准支持开发者能够将 HTML 页面的功能封装为自定义元素

    注册自定义元素需要调用CustomElementRegistry.define()方法,CustomElementRegistry是一个接口,一般使用它的实现类customElements

    define方法有三个参数:

    • 自定义标签名(需要复合DOMString标准,不能是单个单词,且其中必须要有短横线。)
    • 封装元素行为逻辑的
    • 包含 extends 属性的配置对象(是一个可选参数,extends属性表示自定义元素继承自哪个元素)

    例如:

    1. // 自定义一个继承自p元素的标签名为my-element的元素
    2. customElements.define('my-element', MyElement, { extends: 'p' });

    对于封装元素行为逻辑的类,我们需要声明一个class继承自HTMLElement。在构造函数中必须先调用super()函数,之后再编写自定义元素的行为逻辑,具体如何封装会在下一节shadowDOM中介绍。

    Web Components 根据配置对象的传与否,自定义元素可分为继承自基本的 HTML 元素、独立的元素。

    在组件类中可以定义以下四种生命周期回调函数的行为:

    • connectedCallback:元素首次被插入文档 DOM 时调用。
    • disconnectedCallback:元素从文档 DOM 中删除时调用。
    • adoptedCallback:元素被移动到新的文档时调用。
    • attributeChangedCallback: 元素增加、删除、修改自身属性时调用,它接受三个参数(属性名、旧值、新值)。

    Shadow DOM

    Shadow DOM 是封装自定义元素的关键。Shadow DOM 就像一个独立的大沙箱,它能够天然做到 CSS 的样式隔离,与其它的DOM元素互不干扰,它的内部包含一个Shadow树。和其他的基本HTML元素一样,Shadow DOM 也是一个附着在DOM树上的节点,这个节点叫作 shadow host,通过shadowRoot对象访问该节点。下面是关于 Shadow DOM 的示意图:

    通过调用 Element.attachShadow()方法来创建一个Shadow DOM并附着到自定义元素上,它返回一个shadowRoot对象,我们所封装的自定义元素其实是封装在ShadowDOM里。attachShadow()方法接受一个包含mode属性的配置对象作为参数,mode 可以是 open 或者 closed,代表是否允许JavaScript操作这个节点。下面,我们声明一个自定义元素类:

    1. class MyElement extends HTMLElement {
    2. constructor() {
    3. // 首先调用super()
    4. super();
    5. const shadowRoot = this.attachShadow({mode= 'open'});
    6. // 接下来,我们可以为shadowRoot添加各种我们想要的东西
    7. }
    8. }

    之后可以通过dom操作为shadowRoot添加节点(包括 style 、link 标签),这样就可以实现一个封装组件了。

    模板内容

    在自定义元素的代码中,我们将html定义在字符串中,这不利于持续的维护。HTML5新增了template标签为 Web Components 的模板开发提供了便利。该标签内定义的内容浏览器并不会渲染,但可以通过dom获取。

    我们在页面上定义一个template标签,并放一个段落文字,这个标签并不会在页面上渲染

    在自定义元素中使用:

    1. customElements.define('my-element',
    2. class extends HTMLElement {
    3. constructor() {
    4. super();
    5. const content = document.getElementById('my-paragraph').content;
    6. const shadowRoot = this.attachShadow({mode: 'open'})
    7. shadowRoot.append(content)
    8. }
    9. })

    插槽

    有时候我们希望用户能够定义部分模板的内容,让组件模板变得更加灵活。

    Web Components 提供了slot元素,是 web 组件内的一个占位符(称作“插槽”)。插槽由其name属性标识,并且允许您在模板中定义占位符,当在标记中使用该元素时,该占位符可以填充所需的任何 HTML 标记片段。我们把template标签里的内容改一下

    <slot name="my-text">My default textslot>

    在注册自定义组件后,可以这么使用:

    1. <span slot="my-text">Let's have some different text!span>

    通过设置slot属性,向组件模板插入自定义内容

    到此,就是 Web Components 技术套的全部内容了。

    最后

    Web Components 并不是最近才出现的,早在 2011 年 Google 就推出了 Web Components 的概念,不过也仅仅只是提出了这样一个概念,并没有去实现它。随着前端技术的发展,Web Components 标准也逐渐完善,虽然存在许多不足,但是后来出现的的React、Vue、Angular等前端框架都受到了Web Components的启发。

    Web Components 是一套原生的开发技术,能够实现跨端、跨框架、微服务的组件化开发,不受环境、框架技术的限制。目前很多大厂对这套技术进行了实践,市面上也出现了很多 Web Components 库。例如:

    • omi
    • lit-element
    • Polymer
    • X-Tag

    尽管如此,Web Components 依然备受争议,想让便利原生的组件化开发,还需要大量的实践与优化。

  • 相关阅读:
    Chip and Ribbon(Round 158)
    Unity 脚本常用特性
    【Java系列】深入解析 Lambda表达式
    MySQL数据库基础01
    R语言使用cph函数和rcs函数构建限制性立方样条cox回归模型、使用anova函数进行方差分析通过p值确认指定连续变量和风险值HR之间是否存在非线性关系
    OpenCV图像处理——矩形(Rect)类的常用操作
    【山东科技大学OJ】1241 Problem B: 编写函数:比较三个数大小 (Append Code)
    单例模式的不同实现方式效果差异
    项目中应该使用nginx还是拦截器来封禁IP
    Linux:软件管理器yum&&编辑器vim
  • 原文地址:https://blog.csdn.net/qq_38334677/article/details/127719839