[译] 复用 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 层手段。这说不上是全部,或许还有其它手段,但已经足够实用了。

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



相关文章
|
5天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
5天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
5天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
5天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
4天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
6天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
4天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
|
19天前
|
数据采集 监控 JavaScript
在 Vue 项目中使用预渲染技术
【10月更文挑战第23天】在 Vue 项目中使用预渲染技术是提升 SEO 效果的有效途径之一。通过选择合适的预渲染工具,正确配置和运行预渲染操作,结合其他 SEO 策略,可以实现更好的搜索引擎优化效果。同时,需要不断地监控和优化预渲染效果,以适应不断变化的搜索引擎环境和用户需求。
|
6天前
|
存储 JavaScript
Vue 组件间如何通信
Vue组件间通信是指在Vue应用中,不同组件之间传递数据和事件的方法。常用的方式有:props、自定义事件、$emit、$attrs、$refs、provide/inject、Vuex等。掌握这些方法可以实现父子组件、兄弟组件及跨级组件间的高效通信。
|
11天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发