zoukankan      html  css  js  c++  java
  • Web Component组件化

    Web Component组件化

    1.什么是Web Component?

    你可能听过一些框架例如:Vue/React,你也可能会知道一些组件库例如: Element-UI/Ant Design.

    拿Vue举例,每一个.vue文件就是一个组件,其中每一个.vue文件中都会有一个模板<template>,最终代码会将这些模板压缩打包在一起形成一个.html文件

    拿Element来说,每一个组件就是一个Web Component,可以多个合用,多次复用!

    对比来说,Web Component就像是一个.vue文件,可复用/拓展性强!


    2.我能用Web Component做什么?

    直接上手,我们来写一个最基本的Web Component!

    2.1.1自定义HTML标签

    <el-dialog></el-dialog>

    仿照Element-UI组件,我们自定义一个HTML标签,这就是一个自定义元素.

    这里要注意:自定义元素名称要求在子其中使用破折号,不能只是一个单词!

    2.1.2定义一个javascript类

    自定义元素有了,接下来我们要定义一个javascript类,用来扩展HTMLElement类.

    <script>
    class ElDialog extends HTMLElement {
      constructor() {
        super();
      }
    }
    </script>

    以上代码包括了:

    • 定义一个ElDialog类继承了HTML元素的特性

    • constructor()调用这个类

    • super()建立正确的原型链.

    • 你可以在这里使用javascript语法

    Web文档上自定义元素的控制者是CustomElementRegistry对象-该对象允许您在页面上注册自定义元素,返回有关已注册哪些自定义元素的信息,等等.

    要在页面上注册自定义元素,请使用CustomElementRegistry.define()方法.

    接下来我们来注册这个自定义元素

    window.customElements.define('el-dialog', ElDialog);

    这样一来,我们就完成了一个自定义元素的注册了!

    But~ 这个自定义元素是空的, 我们向里面加入内容

    <body>
    <el-dialog></el-dialog>
        
    <script>
    class ElDialog extends HTMLElement {
      constructor() {
        super();
          this.render();
      }
        
      render() {
          this.obj = document.createElement('div')
          this.obj.innerHTML = `
          <div class="box">
            <div class="title">这是一个标题</div>
            <div class="content">这是内容</div>
          </div>
          `
          this.append(this.obj)
      }
    }
    window.customElements.define('el-dialog', ElDialog);
    </script>
    </body>
    • 定义一个javascript函数render(),这个函数在javascript类创建时调用

    • 这个函数创建了一个<div></div>元素

    • 使用模板字符串向创建的这个div元素中插入了HTML元素,

    • this.append(this.obj): 将整个DOM结构插入了自定义元素实例

    现在,你已经实现了基本的Web Component!

    可是,这些数据是写死的怎么能行呢?

    我们来实现动态数据:

    <body>
      <el-dialog title="这是动态标题" content="这是动态内容"></el-dialog>
    ​
      <script>
        class ElDialog extends HTMLElement {
          constructor() {
            super();
            // 获得自定义元素的属性
            let attr = this.attributes;
            // 定义数据对象,使用三元表达式
            this._data = {
              title: attr.title ? attr.title.value : '默认的标题',
              content: attr.content ? attr.content.value : '默认内容'
            }
            this.render()
          }
    ​
          render() {
            this.obj = document.createElement('div')
            // 动态渲染数据
            this.obj.innerHTML = `
              <div class="box">
            <div class="title">${ this._data.title }</div>
            <div class="content">${ this._data.content }</div>
              </div>
              `
            this.append(this.obj)
          }
        }
        window.customElements.define('el-dialog', ElDialog);
      </script>
    </body>

    哇喔~~~现在数据已经动态渲染出来了,使用谷歌浏览器打开看一下,是不是很酷!

    2.1.3进阶 template

    使用上面的DOM结构,你可能会感觉有点麻烦

    别急~

    上面我说过 Web Component就像是一个.vue文件,可复用/拓展性强!为什么这么说呢, 一起来看接下来的代码~~~

    <body>
      <el-dialog
      title="这是动态标题"
      content="这是动态内容"
      img="http://wuliwu.top/logo.png"
      ></el-dialog>
      <template id="myElDialog">
        <style>
          .box {
            display: inline-block;
            text-align: center;
            border: 1px solid #dedede;
            padding: 40px;
          }
    ​
          .title {
            font-size: 24px;
            color: #333;
          }
    ​
          .content {
            font-size: 16px;
            color: #666;
          }
        </style>
        <div class="box">
          <img>
          <div class="title"></div>
          <div class="content"></div>
        </div>
      </template>
    ​
      <script>
        class ElDialog extends HTMLElement {
          constructor() {
            super();
    ​
            var templateElem = document.getElementById('myElDialog');
            // 深度克隆
            var content = templateElem.content.cloneNode(true);
            content.querySelector('img').setAttribute('src', this.getAttribute('img'));
            content.querySelector('.title').innerHTML = this.getAttribute('title')
            content.querySelector('.content').innerText = this.getAttribute('content')
            this.appendChild(content);
          }
        }
    ​
        window.customElements.define('el-dialog', ElDialog);
      </script>
    </body>

    哦呵~~~出现了很熟悉的的东西<template> 模板标签, 里面有style样式,有DOM结构

    我们来看一下效果图和DOM结构:

    这样一看,是不是和.vue文件很像?

    • 有模板<template>, 有样式<style>, 有脚本<script>

    • 哪里需要哪里调用,只需调用<el-dialog>自定义元素就行了

    • 数据放在自定义元素的属性值中, 是不是感觉和 vue 中的 slot 插槽类似?

    2.1.4 Shadow Dom

    将Web Component的代码隐藏起来,DOM与外部DOM隔离,内部任何代码都无法影响外部.

    使用方法this.attachShadow()开启Shadow DOM

    <script>
    class ElDialog extends HTMLElement {
      constructor() {
        super();
        var shadow = this.attachShadow( { mode: 'closed' } );
    ​
        var templateElem = document.getElementById('myElDialog');
        // 深度克隆
        var content = templateElem.content.cloneNode(true);
        content.querySelector('img').setAttribute('src', this.getAttribute('img'));
        content.querySelector('.title').innerHTML = this.getAttribute('title')
        content.querySelector('.content').innerText = this.getAttribute('content')
        shadow.appendChild(content);
      }
    }
    ​
    window.customElements.define('el-dialog', ElDialog);
    </script>

    这样,一个完整的Web Component组件就已经完成了, 是不是很简单,没有像vue框架那么复杂.


    3.Web Component的好处是什么?

    Web组件是一套不同的技术,允许您创建可重用的自定义元素(其功能与其他代码封装在一起),并在Web应用程序中使用它们.

    使用简单, 能够提升开发效率!


    4.Web Component未来的发展方向如何?

    目前而言:

    • Firefox(版本63),Chrome和Opera中默认支持Web组件。

    • Safari支持许多Web组件功能,但少于上述浏览器。

    • Edge正在实施。

    • 可以使用一些第三方库实现支持!

    接下来, 让我们静待佳音,相信在不久的将来Web Component将会普及!

     

    万码皆同源,越学越简单!
  • 相关阅读:
    学习笔记(4)---JQuery
    学习笔记---ES6
    angular.js的学习笔记(1)
    vue.js学习笔记(1)
    HTML5“爱心鱼”游戏总结
    学习笔记(3)---综合
    学习笔记(2)---CSS中的易混淆点
    学习笔记(1)----水平垂直居中的方法
    javascript:void(0)是什么意思
    private Int32? m_shopid;
  • 原文地址:https://www.cnblogs.com/chalkbox/p/14854190.html
Copyright © 2011-2022 走看看