在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
写在前面最近致力于研究 Web components(以下简称WC),并且也初有成效的拿到了一定的结果,但今天想回过头来重新审视一下 WC。 WC 到底是什么?简单的讲,Web Component 就是把组件封装成 html 标签的形式,并且在使用时不需要写额外的 js 代码。 组件是前端的发展方向,抛开周边技术生态,单纯看 React 和 Vue 都是组件框架。因此,WC 可以视为原生标签的拓展/延伸,说到底,它依旧是一个标签! 类似 谷歌公司由于掌握了 Chrome 浏览器,一直在推动浏览器的原生组件,即 Web Components API。 相比第三方框架,原生组件简单直接,符合直觉,不用加载任何外部模块,代码量小。貌似一切完美,似乎大有可以用来替换React、Vue之类的趋势。 目前存在的缺陷与其它 web 框架一起使用存在一些小问题,会给开发体验上造成一些困扰。 1、组件内部事件的回调比如,一个弹窗组件( 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 内部自定义事件 <my-dialog></my-dialog> <script> export default { created() { document.addEventListener('okBtnFn', function(){ // 点击弹窗按钮,触发回调事件 }); } } </script> 2、组件样式覆盖对于开发者来说,难免会遇到需要调整组件内部样式的时候。无论你是使用 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> 提交的时候无法获取 5、其它此外,缺少数据绑定和状态管理也是 WC 存在的缺陷,此处不再赘述。 写在后面WC 指在丰富 HTML 的 DOM 特性,让 HTML 拥有更强大的复用能力 WC 可以直接当做原生标签,在任何前端框架和无框架中运行 结合当下的主流技术栈来说,WC 当前主要问题在于复杂的组件中,数据通信和事件传递存在一定使用成本 兼容问题,比如可以覆盖内部样式的 以上就是Web componentd组件内部事件回调及痛点剖析的详细内容,更多关于Web componentd事件回调及痛点的资料请关注极客世界其它相关文章! |
请发表评论