当前位置: 欣欣网 > 码农

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

2024-05-06码农

模拟面试、简历指导、入职指导、项目指导、答疑解惑 可私信找我~已帮助100+名同学完成改造!

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心~

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

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

    拓展点:

  • 在最初阶段,我尝试通过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

    结语

    我是林三心

  • 一个待过 小型toG型外包公司、大型外包公司、小公司、潜力型创业公司、大公司 的作死型前端选手;

  • 一个偏前端的全干工程师;

  • 一个不正经的掘金作者;

  • 逗比的B站up主;

  • 不帅的小红书博主;

  • 喜欢打铁的篮球菜鸟;

  • 喜欢历史的乏味少年;

  • 喜欢rap的五音不全弱鸡如果你想一起学习前端,一起摸鱼,一起研究简历优化,一起研究面试进步,一起交流历史音乐篮球rap,可以来俺的摸鱼学习群哈哈,点这个,有7000多名前端小伙伴在等着一起学习哦 -->

  • 广州的兄弟可以约饭哦,或者约球~我负责打铁,你负责进球,谢谢