Web Components 取代 Vue?我觉得不太行!

2024年 5月 6日 106.5k 0

Web Components

原因

探讨使用Web Components的原因,我们已经知道像 Vue 和 React 这样的成熟框架存在,但是有没有深入思考过为什么选择使用这些框架?核心理由无非是为了减少编码工作量,通过框架减少代码重复,尽管这同时引入了一些原生不支持的特性,从而增加了一定的复杂性。当我了解到Web Components时,我开始思考是否可以用它来取代 Vue,因为 Vue 的主要优势之一就是能够实现组件的封装和复用

构成

Web Components 由三个主要部分构成,与Vue的模板非常相似:

  • 自定义元素(Custom Element): 这是一组JavaScript API,使你能够定义自定义元素及其行为,以便根据需要在用户界面中使用它们
  • 影子DOM(Shadow DOM): 这也是一组JavaScript API,用于将一个封闭的“影子”DOM树附加到元素上(与主文档DOM分开渲染),并管理其相关功能。这样,你可以确保元素的功能是私有的,因此它们可以被脚本化和样式化,而不会与文档的其他部分产生冲突
  • HTML模板(HTML Template): template 和 slot 元素让你能够创建不会立即显示在渲染页面中的标记模板。然后,这些模板可以作为自定义元素结构的基础,被反复使用

使用

接下来说一下 Web Components 的基本使用~

自定义组件

创建一个基础的自定义组件包含以下步骤:

  • 1、继承: 自定义元素需要通过继承HTMLElement类(或其子类)来创建
  • 2、创建模板: 使用document.createElement('template')来创建一个新的模板元素
  • 3、获取影子DOM: 通过元素的attachShadow方法获取影子DOM,为元素提供封装的DOM结构
  • 4、添加内容: 将模板内容通过appendChild方法添加到影子DOM中。使用cloneNode方法克隆节点,避免对原始模板的污染。
  • 5、定义组件: 使用customElements.define('component-tag-name', ComponentClassName)来定义组件,使其可在页面中使用

至此,一个最基础的自定义组件创建完成

Web Components 取代 Vue?我觉得不太行!-1图片

拓展点:

  • 在最初阶段,我尝试通过WebComponent.html的形式编写自定义组件,这样可以直接在标签中写样式和HTML,便于编辑器提供代码提示和格式化。然而,由于当前标签不支持直接导入HTML文件,除非通过HTTP GET请求加载外部HTML,但这种方法似乎违背了初衷。
  • 要监听属性的变化,必须通过static get observedAttributes静态方法声明哪些属性是被监听的。之后,就可以在attributeChangedCallback回调函数中捕获属性变化。
  • 自定义元素也拥有简化的生命周期钩子,虽然只有三个,但它们的存在使得状态管理变得简单。
  • 支持使用插槽(slots),类似于Vue,可以通过的方式来实现内容的插入。

在html中使用

  • 当引入自定义组件时,建议使用defer属性,这样可以确保脚本在文档解析完成后再执行,避免潜在的执行顺序问题。自定义组件的标签使用方式与Vue非常相似,即使用组件在define时指定的名称,并通过slot="slot-name"来指定插槽的名称。在Vue项目中,可以通过简单地导入组件的JavaScript文件(例如import "./components/WebComponent/WebComponent.js";)来使用这些自定义元素。

Web Components 取代 Vue?我觉得不太行!-2图片

在实际使用中,可能会遇到一些挑战:

  • 通常情况下,自定义组件内部和父组件都会包含一些业务逻辑,这可能需要父组件向子组件暴露某些方法。例如,在自定义组件被加入到页面(即在connectedCallback被调用)之后,可能需要通知父组件,这时可以通过调用在父组件中定义的this.ready()方法。为了避免connectedCallback在ready方法定义之前执行而导致错误,推荐在引入自定义组件的脚本标签中加上defer
  • 若需调用自定义组件的方法,必须确保自定义组件已经完全创建好。因此,在示例中通过定义一个ready方法,并在connectedCallback调用之后执行它,或者等待页面的onload事件触发后执行。这意味着定义和调用之间的执行顺序需要特别注意,以避免由于执行顺序引起的问
  • 监听属性变化时,应使用setAttribute方法来修改属性值,因为直接修改属性(如extendP.attributes['size']=200)不会触发属性监听回调
  • 关于插槽(slot)传值的问题,目前似乎没有直接的方法来实现

简而言之,虽然自定义组件的使用看似简单直接,但在实际开发中还是需要注意脚本加载顺序、组件通信和属性监听等细节问题,以确保组件能够正确无误地运行

参考文章:https://juejin.cn/post/7309693162368565299

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论