[译] 复用 Vue 组件的 6 层手段

简介: [译] 复用 Vue 组件的 6 层手段

原文:michaelnthiessen.com/6-levels-of…

在编写代码的时候,谁都想“少干活、多办事”。以组件而言,我们希望它能被不止一次地复用。

一些组件仅需基本的复用性。

另一些则需要更复杂的技术以充分利用。

我认为复用性有 6 中不同的层级,这里大体上来看一下:

1. 模版化

不同于将代码随处复制/粘贴的是,借助模版化可以将其包裹在组件内部。

当复用组件 -- 而不是直接拷贝代码时,给我们带来了两个好处:

  1. 未来的改动变得简单的多,因为只需要在一处进行
  2. 无需再记住类似代码被拷贝到的哪几个甚至上百个地方了

这简直太基础了,也是谈及复用性时最常被说起的。

更高一个层级的就有意思些了:

2. 配置

对于某些组件,使用起来是需要变化的。

一个 Button 组件会有个基本的样子,或许也要支持带个图标。与其为每个版本都重新创建一整个新组件,不如使用属性切换其类型。

添加这些属性通常不会对组件改动太多,但却带来了组件使用的更多灵活性。

注意:这跟使用属性影响状态或数据是不同的,比如一个 loading prop 或 disabled prop.

3. 适配性

配置的最大问题在于缺乏远见。要预见并支持未来的需求,就得向组件中加入很多属性。

但如果让组件变得“可适配”,在不用改变组件的前提下,就能让其支持我们甚至未曾设想到的场景。

实现的方法是用一个 slot,从父组件中传入一块模版置标。

比如,与直接在 Button 组件上使用一个 text 属性不同的是,我们可以使用 default slot:


<!-- Button.vue -->
<template>
  <button
    class="btn btn--default"
    @click="$emit('click')"
  >
    <slot />
  </button>
</template>

这样一来,就不受制于传递一个 stringnumber 还是别的什么了。

如果要增加一个 loading 旋转动画,又不想改动 Button 组件,这样做就好了:


<template>
  <Button>
    <img
      v-if="loading"
      src="spinner.svg"
    />
    摁我
  </Button>
</template>

4. 反转

与向子组件中传入一整块模版置标又有所不同的是,我们还能传入一组指令,以决定其 如何 渲染。

打个比方,这就像自己烹饪和叫外卖的对比。当你按照菜谱自己动手时,虽然要费些事,但却尽在掌握 -- 你可以自己掌控“少许味精”是多少,甚至直接扔掉菜谱自己发挥都可以。

在 Vue 中,使用 scoped slot (作用域插槽) 就可以达到目的,为组件增加更多的灵活性了。

(译注 - 官网上的例子):


<!-- 子组件 CurrentUser -->
<span>
  <slot v-bind:user="user">
    {{ user.lastName }} <!--默认值-->
  </slot>
</span>
<!-- 父组件 -->
<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.age < 10
        ? slotProps.user.lastName
        : `Mr. ${slotProps.user.firstName}` }}
  </template>
</current-user>

5. 扩展

使用 Vue 中的 named slots (具名组件) 可以在组件中添加一个或多个扩展点。再结合上述的适配反转,就具备了最大化组件复用性的必要技术。下一步就是在组件中贯彻这些技术,以更简单地扩展其行为。

下例中,一个 Modal 组件中分别有 headerdefaultfooter 几个 slots:


<template>
  <div class="modal">
    <slot name="header">
      <h2>{{ title }}</h2>
    </slot>
    <!-- Default slot for main content -->
    <slot />
    <slot name="footer">
      <Button @click="closeModal">
        Close
      </Button>
    </slot>
  </div>
</template>

例子相当简单,但我们已经有了多种扩展这个组件的选项了:

  1. 只是覆写 default slot 来显示内容
  2. 显示默认内容,并增添 header slot 部分
  3. 显示默认内容,并增添 footer slot 以显示几个按钮
  4. 显示所有 slots 的内容

6. 嵌套

如果我们将“扩展点”逐层传递,就能达到最终目的。这乍听起来有点繁琐,但确实有用,特别是在大型应用的环境中。

从一个完成相当普通功能的基础组件 A 开始;下一个组件 B 比 A 稍微不那么普通一些,并在很少的方面扩展 A。之后周而复始,直到你拥有了最终能真正工作的组件。

类似于经典的 OOP 例子,我们可以从一个相当通用的 动物 组件扩展到更特别一些的 哺乳动物,接下来是 并最终得到 贵妇犬

要是我们的目的就只是 贵妇犬,那这一切确实是费了瞎劲;但在大型应用中,我们要从同样但基础想法上扩展出各种各样的结果 -- 比如从 中分化出 金毛京巴,或从 哺乳动物 中得到 猫科动物 并实现 老虎狮子

总结

本文列出了复用 Vue 组件的 6 层手段。这说不上是全部,或许还有其它手段,但已经足够实用了。

✨ 更多“组件化”的文章  ✨



相关文章
|
21天前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
18天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
119 64
|
18天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
26 8
|
18天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
21天前
|
JavaScript 前端开发 开发者
Vue是如何劫持响应式对象的
Vue是如何劫持响应式对象的
20 1
|
21天前
|
JavaScript 前端开发 API
介绍一下Vue中的响应式原理
介绍一下Vue中的响应式原理
27 1
|
21天前
|
JavaScript 前端开发 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
21天前
|
存储 JavaScript 前端开发
介绍一下Vue的核心功能
介绍一下Vue的核心功能
|
23天前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
|
25天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
27 1
vue学习第一章