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

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

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

责任编辑:武晓燕 来源: 前端之神
相关推荐

2022-01-11 20:42:28

CSS Chrome浏览器

2024-02-26 09:13:35

WebComponents开源项目

2020-03-04 10:36:11

互联网数据技术

2014-05-26 15:35:55

Web组件Web Compone

2022-11-12 17:36:51

Web前端开源

2014-01-17 14:39:18

12306 抢票

2022-02-25 10:44:38

Web前端框架

2023-11-03 08:04:47

Web微前端框架

2022-02-10 22:24:05

DOM结构工具

2022-02-09 20:20:30

浏览器组件化网页

2017-09-06 10:01:58

戴尔

2014-04-08 14:56:06

开源开源胜利

2014-05-19 10:55:12

Web组件Web Compone

2022-12-08 17:32:25

chatGPT人工智能聊天

2019-04-02 10:39:42

WiFiLiFi5G

2014-05-26 17:26:16

Web ComponeGMU

2022-02-18 08:10:43

MyCardTemplates布局

2016-08-30 21:09:33

2023-08-10 13:57:50

模型AI

2022-06-16 07:31:41

Web组件封装HTML 标签
点赞
收藏

51CTO技术栈公众号