写在前面

最近致力于研究 Web components(以下简称WC),并且也初有成效的拿到了一定的结果,但今天想回过头来重新审视一下 WC。

WC 到底是什么?

简单的讲,Web Component 就是把组件封装成 html 标签的形式,并且在使用时不需要写额外的 js 代码。

组件是前端的发展方向,抛开周边技术生态,单纯看 React 和 Vue 都是组件框架。因此,WC 可以视为原生标签的拓展/延伸,说到底,它依旧是一个标签!

类似 <video></video> 标签,相比于原生标签,它多了更为丰富的样式和可操作属性。

谷歌公司由于掌握了 Chrome 浏览器,一直在推动浏览器的原生组件,即 Web Components API。

相比第三方框架,原生组件简单直接,符合直觉,不用加载任何外部模块,代码量小。貌似一切完美,似乎大有可以用来替换React、Vue之类的趋势。

目前存在的缺陷

与其它 web 框架一起使用存在一些小问题,会给开发体验上造成一些困扰。

1、组件内部事件的回调

比如,一个弹窗组件(<my-dialog></my-dialog>)中的确定按钮,那么它的事件是如何触发的呢?

class myDialog extends HTMLElement {
  // ...
  connectedCallback() {
    const shadowRoot = this.attachShadow({ mode: 'open' });
    shadowRoot.innerHTML = `
      <div class="dialog">
        <div class="dialog-content">
          <div class="dialog-body">
            弹窗内容
          </div>
 
          <button id="okBtn">确定</button>
        </div>
      </div>
    `;
     shadowRoot.querySelector('#okBtn').addEventListener('click', () => {
      // 组件内部定义事件
      this.dispatchEvent(new CustomEvent('okBtnFn'));
    });
  }
} 
customElements.define('my-dialog', myDialog);

现在方案是 custom element 内部自定义事件 new CustomEvent(),外部用 addEventListener监听。这样的写法是很丑陋的,仿佛又回到了原生 JS 写应用的时代。

<my-dialog></my-dialog> 
<script>
  export default {
    created() {
      document.addEventListener('okBtnFn', function(){
        // 点击弹窗按钮,触发回调事件
      });
    }
  }
</script>

2、组件样式覆盖

对于开发者来说,难免会遇到需要调整组件内部样式的时候。无论你是使用antdvant还是使用其它组件库,但 WC 的 CSS 防污染机制导致你很难修改内部样式。这需要你付出一些代价来变相的修改内部样式

3、组件内部资源相对路径问题

就目前来说,任何直接基于 Custom Element v1, Template 和 HTML Import 的组件都无法做到完全资源独立 —— 在不知道使用方环境且不给使用方增加额外限制的情况下使用内部封装的任何资源文件。比如如果你有一个自定义 icon 组件:

class MyIcon extends HTMLElement {
    static get observedAttributes() { return ['name','size','color'] }
    constructor() {
        super();
        const shadowRoot = this.attachShadow({ mode: 'open' });
        shadowRoot.innerHTML = `
            <svg class="icon" id="icon" aria-hidden="true" viewBox="0 0 1024 1024">
                <use id="use"></use>
            </svg>        
    } 
    attributeChangedCallback (name, oldValue, newValue) {
        if( name == 'name' && this.shadowRoot){
            // 如果使用的项目中,根目录没有 icon.svg 文件,那就 gg
            this.use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', `./icon.svg#icon-${newValue}`);
        }
    }
}
customElements.define('my-icon', MyIcon);

如果使用的项目中,根目录没有 icon.svg 文件,那就 gg。如果你在这里使用 cdn 路径,就会出现跨域问题。

4、form表单类组件 value 获取问题

Shadow DOM 中包含有 <input>、<textarea> 或 <select> 等标签的 value 不会在 form 表单中自动关联。

示例代码:

// web component
class InputAge extends HTMLElement {
  constructor() {
    super();
  }  
// connect component
  connectedCallback() {
    const shadow = this.attachShadow({ mode: 'closed' });
    shadow.innerHTML = `<input type="number" placeholder="age" min="18" max="120" />`;
  }
}
// register component
customElements.define( 'input-age', InputAge );

WC 组件被使用后

<form id="myform">
  <input type="text" name="your-name" placeholder="name" />
  <input-age name="your-age"></input-age>
 
  <button>submit</button>
</form>
 
<script>
 const form = document.getElementById('myform');
 
  form.addEventListener('submit', e => {
    
    e.preventDefault();
    console.log('Submitted data:');
 
    const data = new FormData(form);
    for (let nv of data.entries()) {
      console.log(`  ${ nv[0] }: ${ nv[1] }`);
    }
 
  });
</script>

提交的时候无法获取 input-age 的 value。当然会有解决方案,但会很复杂。

5、其它

此外,缺少数据绑定和状态管理也是 WC 存在的缺陷,此处不再赘述。

写在后面

WC 指在丰富 HTML 的 DOM 特性,让 HTML 拥有更强大的复用能力

WC 可以直接当做原生标签,在任何前端框架和无框架中运行

结合当下的主流技术栈来说,WC 当前主要问题在于复杂的组件中,数据通信和事件传递存在一定使用成本

兼容问题,比如可以覆盖内部样式的 :part 方法

以上就是Web componentd组件内部事件回调及痛点剖析的详细内容,更多关于Web componentd事件回调及痛点的资料请关注Devmax其它相关文章!

Web componentd组件内部事件回调及痛点剖析的更多相关文章

  1. 解决JSP开发中Web程序显示中文三种方法

    JSP显示中文方法小结

  2. 浅谈Web页面向后台提交数据的方式和选择

    下面小编就为大家带来一篇浅谈Web页面向后台提交数据的方式和选择。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. JavaScript web网页入门级开发详解

    Web框架正如前文所述, 在整个项目结构中处于一个承上启下的位置, 是整个项目的核心组件, 所以这次来聊聊Web框架的一些普适性特性和如何快速的入门

  4. 安装Node.js并创建Web程序

    这篇文章介绍了安装Node.js并创建Web程序的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  5. Vue3 构建 Web Components使用详解

    这篇文章主要为大家介绍了Vue3 构建 Web Components使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  6. Java Web中Ajax技术使用方法介绍

    ajax技术是使页面能局部刷新的一种技术,下面这篇文章主要给大家介绍了关于JavaWeb之Ajax的基本使用与实战案例的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

  7. JWT Json Web Token全面详解

    这篇文章主要为大家介绍了JWT Json Web Token全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>

  8. SpringBoot web开发源码深入分析

    Web开发的核心内容主要包括内嵌的Servlet容器和SpringMVCSpringBoot使用起来非常简洁,大部分配置都有SpringBoot自动装配,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  9. AngularJs Understanding the Controller Component

    本文主要介绍AngularJs Understanding the Controller Component的内容,这里整理了相关资料,及简单示例代码,有兴趣的小伙伴可以参考下

  10. 一篇文章让你彻底弄懂JS的事件冒泡和事件捕获

    这篇文章主要介绍了一JS的事件冒泡和事件捕获,通过代码举例详细描述了两者之间的差别,需要的朋友可以参考下

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部