期待Web Component的未来

Web Component本身不是一个规范,而是一组技术的应用,Web Component现阶段主要分为三部分:Custom elementShadow DOMTemplate。通过它们的搭配使用,可以让我们在不借助第三方框架(react,vue)的情况下,构建独立的,可重用的自定义组件。

Custom element(自定义元素)

Custom element 是一组 javasrcipt API,它允许我们自定义一些定制元素及行为。

<body>
		<!-- 组建使用 -->
    <box-div color="orange" text="hello"></box-div>
  </body>

	<!-- 组建定义 -->
  <script>
    class boxDiv extends HTMLElement {
      constructor() {
        super();
        this.style.color = this.getAttribute('color');
        this.append(this.getAttribute('text'));
      }
    }
    window.customElements.define('box-div', boxDiv);
  </script>

在这里插入图片描述

js提供了customElements.define api,用来注册自定义元素,customElements.define()接收三个参数:

  • 符合命名标准的参数名称(不能是单个单词,且必须要有短横线)
  • 用于定义行为的类
  • 可选参数:一个包含 extends属性的配置对象,指定所创建元素继承于哪个内置的HTML元素。

Custom element有两种定义元素的方式,没有传递第三个参数表示独立创建,不继承内置元素。在使用时可以直接写成HTML标签的形式来使用,例如<word-count> 或者通过js创建document.createElement(“word-count”)

若在定义元素时指定了所扩展的元素,表示继承创建。在使用时则需要先写出基本的元素标签,并通过is 指定所扩展的元素。

customElements.define('word-count', WordCount, { extends: 'p'});

// 使用方式
<p is="word-count"></p>
// 或
document.createElement("p", { is: "word-count" } )

它还可以指定一些回调函数,它们将在元素不同的生命时期被调用

  • connectedCallback:当 custom element 首次被插入文档 DOM 时,被调用。
  • disconnectedCallback:当 custom element 从文档 DOM 中删除时,被调用。
  • adoptedCallback:当 custom element 被移动到新的文档时,被调用。
  • attributeChangedCallback: 当 custom element 增加、删除、修改自身属性时,被调用。
class boxDiv extends HTMLElement {
	static get observedAttributes() {
    return ['class', 'style'];
  }
  constructor() {
    super();
    this.style.color = this.getAttribute('color');
    this.append(this.getAttribute('text'));
  }
	public connectedCallback() {
	  console.log('元素插入DOM中.');
	}
	public disconnectedCallback(){
		console.log('元素被删除.');
	}
	public adoptedCallback(){
		console.log('元素被移动.');
	}
	public attributeChangedCallback(name, oldValue, newValue){
		console.log('元素属性变更.' name,oldValue, newValue);
	}
}

注:想在某个元素属性变化后,触发attributeChangedCallback()回调函数,需要先必须监听这个属性。这可以通过定义observedAttributes() get 函数来实现,observedAttributes()
函数体内包含一个 return 语句,返回一个数组,包含了需要监听的属性名称。监听后。每当元素的属性变化时,attributeChangedCallback()回调函数会执行。我们可以查看属性的名称、旧值与新值。

通过这些生命周期函数,我们可以动态的变更我们的web组件。

Shadow DOM(影子DOM)

Shadow DOM也有一组javascript API,他不是一个新事物,它允许我们在常规DOM元素上附加一个独立隐藏的特殊类型DOM元素。这部分的代码与外部代码相互隔离。内部的任何代码都无法影响外部。

通过Shadow DOM和Custom element搭配的方式,可以保证自定义元素的独立。使其不会影响到它外部的元素。

在这里插入图片描述

基本用法

可以使用 Element.attachShadow() 方法来将一个 shadow root 附加到任何一个元素上。它接受一个配置对象作为参数,该对象有一个 mode 属性,值可以是 open 或者 closed:

let shadow = elementRef.attachShadow({mode: 'open'});
let shadow = elementRef.attachShadow({mode: 'closed'});

open 表示可以通过页面内的javascript方法来获取Shadow DOM。

let myShadowDom = myCustomElem.shadowRoot;

如果你将一个 Shadow root 附加到一个 Custom element 上,并且将 mode 设置为 closed,那么就不可以从外部获取 Shadow DOM 了。myCustomElem.shadowRoot 将会返回 null。

实现一个简单的tooltip

<body>
    <popup-info text="一个点击可直接暴富的朴素按钮">button</popup-info>
  </body>
  <script>
    class PopUpInfo extends HTMLElement {
      constructor() {
        super();

        const shadow = this.attachShadow({ mode: 'open' });

        const style = document.createElement('style');
        style.textContent = `
      .wrapper {
        position: relative;
        top: 100px;
        left: 10px;
      }
      .info {
        font-size: 14px;
        width: 200px;
        display: inline-block;
        border: 1px solid black;
        padding: 10px;
        background: white;
        border-radius: 10px;
        opacity: 0;
        transition: 0.6s all;
        position: absolute;
        bottom: 20px;
        left: 10px;
        z-index: 3;
      }
      .title:hover + .info, .title:focus + .info {
        opacity: 1;
      }
    `;
        shadow.appendChild(style);

        const wrapper = document.createElement('span');
        wrapper.setAttribute('class', 'wrapper');
        shadow.appendChild(wrapper);

        // title信息
        const titleDom = document.createElement('span');
        titleDom.setAttribute('class', 'title');
        const title = this.innerHTML;
        titleDom.append(title);
        wrapper.appendChild(titleDom);

        // tooltip信息
        const infoDom = document.createElement('span');
        infoDom.setAttribute('class', 'info');
        const text = this.getAttribute('text');
        infoDom.textContent = text;
        wrapper.appendChild(infoDom);
      }
    }

    customElements.define('popup-info', PopUpInfo);
  </script>

定义一个自定义DOM,然后创建一个shadowDOM,给shadowDOM新增子标签style titleSpan infoSpan

最后将shadowDOM附加到自定义DOM上。一个简单的tooltip就实现了。

目前看起来还有一些问题,比如我写style的方式是用模版字符串写的。比如我用的jsAPI生成的dom元素。可读性较差。再比如目前的提示信息只接收字符串,不支持DOM类型。这些问题可以使用template和slot来解决。

HTML template(HTML 模板)

HTML提供了和标签,标签和其子内容不会在DOM中呈现。但仍然可以使用JS去引用它。借助这个特性。可以让我们创建一个用来灵活填充web组件的模版。

<template id="my-paragraph">
  <p>My paragraph</p>
</template>

这段代码不会在页面中呈现,但却可以通过document.querySelector() 等API获取

let template = document.querySelector('#my-paragraph');

标签则允许我们在模版中定义占位符,在使用该模版时,该占位符可以填充所需的任何HTML标记片段。

通过<template> 标签和插槽<slot>,我们可以将想要的元素定制成一个模版。随取随用。

在web组件 中使用模版和插槽

<popup-info>
  <a href="http://www.baidu.com" slot="info"
        >一个点击可直接暴富的朴素按钮</a
      >
  <span slot="title">button</span>
</popup-info>
<template id="tooltip-template">
  <style>
    .wrapper {
      position: relative;
      top: 100px;
      left: 10px;
    }
    .info {
      font-size: 14px;
      width: 200px;
      display: inline-block;
      border: 1px solid black;
      padding: 10px;
      background: white;
      border-radius: 10px;
      opacity: 0;
      transition: 0.6s all;
      position: absolute;
      bottom: 20px;
      left: 10px;
      z-index: 3;
    }
    .title:hover + .info,
    .title:focus + .info {
      opacity: 1;
    }
  </style>
  <span class="wrapper">
    <span class="title"><slot name="title">title</slot></span>
    <span class="info"><slot name="info">info</slot></span>
  </span>
</template>

<script>
    class PopUpInfo extends HTMLElement {
      constructor() {
        super();

        const template = document.querySelector('#tooltip-template');
        let templateContent = template.content;

        const shadow = this.attachShadow({ mode: 'open' });
        shadow.append(templateContent.cloneNode(true));
      }
    }

    customElements.define('popup-info', PopUpInfo);
  </script>

因为style较长,也可以采用link标签方式在外部引入

Web Component实践

基础组件库

市面上已经有很多基于 Web Components 实现的跨框架 UI 组件库。 它可以同时在任意框架或无框架中使用。

Svelte

scelte是目前比较火的前端框架,他有一个特点就是可以自定义组件转成通用的web组件(web component)。在多团队协同完成的大项目中,各个团队可能使用不同的框架版本,甚至不同的框架,这让不同项目之间的组件复用变得困难。这种情况下Svelte就变成了沟通跨越框架鸿沟的桥梁,使用Svelte开发的无框架依赖的Web Components,可以在各个框架间复用。

微前端

微前端有几个基本概念: 技术栈无关、应用间隔离、独立开发。目前 Web Components 都符合。在一些微前端方案里就采用了Web Component的模式。

Web Component的缺点

  • 再日常开发中,难免会遇到需要调整组件内部样式的时候,但由于shadowDOM的隔离机制,会导致我们很难去修改内部的样式。
  • 在一些复杂的组件中,数据通信和事件传递存在一定使用成本。

结语

Web Component虽早在11年就已推出,且一直发展至今。他的潜力有目共睹,但目前还有很长的路要走。
或许在以后,我们将不再依赖第三方框架,直接使用原生技术来开发页面也说不定。

end.

漂亮的ComponentArtWebUI及Demo源码 产品特征: 先进的用户界面控件套装:为高级Web应用程序开发提供了16个优质的用户界面控件。 专为ASP.NET而设计:为三个先进且更强大的框架而设计:ASP.NET 1.0, ASP.NET 2.0和ASP.NET AJAX。 强大的客户端呈现技术:行业中最先进的Web用户界面技术。 深入整合ASP.NET AJAX:最理想的完全应用AJAX框架的控件。 全面的帮助文档和技术支持:提供了完善的产品在线帮助文档和全面的技术支持资源。 企业级服务和培训:为企业级项目开发定制专门的产品咨询和培训服务。 灵活的产品授权:针对开发者,服务和企业级应用提供不同的授权方式。 ComponentArt Web.UI 2007.1 更新信息 ComponentArt Web.UI 2007.1 版本中发布了三个最新的控件: ToolBar for ASP.NET ComboBox for ASP.NET Dialog for ASP.NET 以下为Web.UI组件2007.1版本中新增的功能特征: ComponentArt Grid 可以在Callback模式中缓存页面 (CallbackCachingEnabled和CallbackCacheSize属性)。 可在Callback模式中预加载页面到缓存中 (CallbackCacheLookAhead属性)。 页面在滑动条经过时可提取页面 (SliderFetchDelay属性)。 客户端滚动事件。 客户端beforeCallback事件。 ColumnResizeRedistributeWidth属性用于控制缩放状态。 ComponentArt Menu 引入(已选)checking和(未选)unchecking项的概念。允许菜单项成为复选框或者单元按钮。 引入(图标透明度)IconVisibility的概念。可使图标只在该项被选中或该项根目录时显示。 添加更多对上下文菜单扩展的控制:(TopGroupExpandDirection, TopGroupExpandOffsetX, TopGroupExpandOffsetY)。 增加了ExpandDisabledItems的布尔值属性。 改进了IE7中的元素覆盖运算法则,优化其执行性能。 ComponentArt MultiPage 增加了IE转换效果 (Transition, TransitionDuration属性)。 Web.UI 2007.1 版本没有进行整体框架的改变,只是在Web.UI 2006.2的基础上进行了改进,所以通过最新的ComponentArt.Web.UI.dll可以很方便的对之前的应用程序进行编译。 ComponentArt Web.UI是全球知名的ASP.NET用户界面控件包,它提供了ComponentArt独特的界面呈现技术,支持强大的AJAX技术,可以为您提供最先进的ASP.NET Web用户界面。ComponentArt Web.UI专为ASP.NET框架设计,它包含16个支持AJAX技术的优质用户界面控件,并可应用在ASP.NET 1.0, ASP.NET 2.0, ASP.NET AJAX框架中。 2008年3月27日,专注于ASP.NET Web.UI及Charting控件开发的ComponentArt又发布了Web.UI的最一代版本:2008.1。该版本有四个框架平台:ASP.NET 1.0、ASP.NET 2.0、ASP.NET Ajax,还有当然是最新的.NET框架支持的ASP.NET 3.5了。 2008.1不仅对其代码的运行效率进行了优化,还最增了一个大家期盼已久的成员:Upload。上传空间虽已不是罕见的东东,可是ComponentArt提供的这款不会让你和你的开发团队失望的。 更主要的是ASP.NET 3.5的版本的发布的,同样,特性和功能都具备的同时,也加入了对LINQ的高度支持。这样,ASP.NET 3.5的开发人员也可以享用到这份大餐喽~ Advanced User Interface Control Suite: Includes 19 Premium User Interface controls for development of sophisticated web applications. Built for ASP.NET: Available in four progressively more powerful framework builds: ASP.NET 1.0, ASP.NET 2.0, ASP.NET AJAX and ASP.NET 3.5. Powerful Client-side Rendering Technology: Featuring the most advanced web user interface technology in the industry. Deepest ASP.NET AJAX Integration: The first true controls to fully exploit the most advanced AJAX framework available. Comprehensive Documentation and Support: Featuring complete product documentation online and all-inclusive technical support resources. Enterprise Consulting and Training: Customized consulting and training services are offered to support Enterprise development projects involving larger teams of developers. Flexible Licensing: Available at Developer, Subscription and Enterprise levels. ComponentArt Web.UI 包含以下用户界面控件 Calendar (日历) Grid (表格) Rotator (旋转器) TabStrip (标签) CallBack (回调) Menu (菜单) SiteMap (地图) ToolBar (工具条) ComboBox (组合框) MultiPage (分页) Snap (抓取) TreeView (树形列表) Dialog (对话框) NavBar (导航条) Splitter (框架分离) WebChart Lite (图表) 如果涉及到安装序列号,请填写:3JKX6-YJW6X-GJJDP app_data为应用到的Sql和Access数据库文件 documentation下为官方的相关文档 DllCode下为控件的源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值