5

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

 1 week ago
source link: https://www.51cto.com/article/787650.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

作者:林三心不学挖掘机 2024-05-06 08:36:30
简而言之,虽然自定义组件的使用看似简单直接,但在实际开发中还是需要注意脚本加载顺序、组件通信和属性监听等细节问题,以确保组件能够正确无误地运行。

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)来定义组件,使其可在页面中使用

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

图片
图片
  • 在最初阶段,我尝试通过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";)来使用这些自定义元素。
图片
图片

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

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

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

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

责任编辑:武晓燕 来源: 前端之神

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK