Web component怎么理解,缺点是什么
Admin 2022-07-12 群英技术资讯 573 次浏览
最近致力于研究 Web components(以下简称WC),并且也初有成效的拿到了一定的结果,但今天想回过头来重新审视一下 WC。
简单的讲,Web Component 就是把组件封装成 html 标签的形式,并且在使用时不需要写额外的 js 代码。
组件是前端的发展方向,抛开周边技术生态,单纯看 React 和 Vue 都是组件框架。因此,WC 可以视为原生标签的拓展/延伸,说到底,它依旧是一个标签!
类似 <video></video>
标签,相比于原生标签,它多了更为丰富的样式和可操作属性。
谷歌公司由于掌握了 Chrome 浏览器,一直在推动浏览器的原生组件,即 Web Components API。
相比第三方框架,原生组件简单直接,符合直觉,不用加载任何外部模块,代码量小。貌似一切完美,似乎大有可以用来替换React、Vue之类的趋势。
与其它 web 框架一起使用存在一些小问题,会给开发体验上造成一些困扰。
比如,一个弹窗组件(<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>
对于开发者来说,难免会遇到需要调整组件内部样式的时候。无论你是使用antd
、vant
还是使用其它组件库,但 WC 的 CSS 防污染机制导致你很难修改内部样式。这需要你付出一些代价来变相的修改内部样式
就目前来说,任何直接基于 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 路径,就会出现跨域问题。
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
。当然会有解决方案,但会很复杂。
此外,缺少数据绑定和状态管理也是 WC 存在的缺陷,此处不再赘述。
WC 指在丰富 HTML 的 DOM 特性,让 HTML 拥有更强大的复用能力
WC 可以直接当做原生标签,在任何前端框架和无框架中运行
结合当下的主流技术栈来说,WC 当前主要问题在于复杂的组件中,数据通信和事件传递存在一定使用成本
兼容问题,比如可以覆盖内部样式的 :part
方法
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本文主要介绍了js获取异步函数数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
这篇文章给大家分享的是React请求远程数据的相关内容,React中请求远程数据的方式有四种,具体怎样实现呢?文中的示例代码介绍得很详细,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。
不断调用generator对象的next()方法,执行generator代码,然后,每次遇到yieldx;返回一个对象,然后暂停。直接用for...of循环迭代generator对象,不需要自己判断done。
当你想到路由时,通常会想到类似react之类的库。但实际上,这些库和框架仍然使用vanillaJavaScript。那么该怎么实现呢?
这篇文章主要为大家详细介绍了Vue实现简易记事本功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008