包装器组件非常有用,可以使你的代码库更有条理、更专业。
包装器组件是通过添加某些自定义功能、样式或其他功能来修改原生元素或第三方库的自定义组件。
本文结束时,你将会学到:
- 包装组件做什么用
- 什么情况下使用
- 怎样写一个包装器组件
为什么要用包装器组件?
正如前面所说的那样,包装器组件对于组织代码和扩展原生或外部元素都很有用。
但是它对我们到底有什么帮助呢?
假设我们要为默认的 text input 构建一个包装器组件。 使用包装器组件会创建自然的继承关系:Parent Element -> TextInputWrapper -> Input。
在 TextInputWrapper 内部可以添加自定义样式、过渡和扩展 input 元素的默认用法。如果没有包装器,则必须直接对所有使用高级输入的组件中的输入元素进行这些编辑。
包装器组件为我们提供了一个可重用组件,可以直接导入并使用。现在如果要修改功能,只需要编辑一个文件,而不是几十个文件。
因此包装器组件不仅可以帮我们使代码尽可能保持整洁,而且还构建了更具模块化和可扩展性的项目。
一个例子
我们知道了包装器组件是什么,以及它们如何发挥作用,接下来看一个例子,为原生的文本输入创建一个包装器组件。
这是基础代码:
<template>
<div>
{{ label }}
<input/>
</div>
</template>
<script>
export default {
props: ['label']
}
</script>
<style scoped>
</style>
在 Vue3 中进行包装非常简单,只需要了解 Vue 实例的属性:$attrs。
$attrs 包含了传递给组件的所有非属性和非发射事件。
在 Vue2 中,如果我们没有在自己的组件中明确定义一个prop,则会被添加到组件的子项的根中。但是如果把callitattrs 实例属性设置为 false,则可以覆盖此属性,并能够用 $attrs 属性通过包装器组件传递数据。
但是在 Vue3 中,不再绑定到子组件的默认绑定,因此没有要覆盖的内容。另外,以前通过 $listeners 属性访问的组件的非发射事件侦听器现在也包含在了 $attrs 中。
<template>
<div>
{{ label }}
<input v-bind='$attrs'/>
</div>
</template>
<script>
export default {
props: ['label']
}
</script>
<style scoped>
</style>
在基本的文本输入可以使用的情况下,可以向包装器组件添加一些自定义。扩展方法是添加自定义事件侦听器,不同的样式或某种 label 属性来标记我们的输入。
现在包装器组件已设置好了,下面是将其包含到组件中的例子:
<text-input
label='hello'
v-model='state.textVal'
placeholder='Hello World'
/>
如果你真的想更深入地了解 Vue3 中的 v-model,$attrs 和 v-bind 的工作原理,请参阅 great slide deck by Chris Fritz
还有什么?
前面介绍的例子是包装器组件的一种非常简单的用法,但是它展示了一个主要用途:包装原生元素以添加更多的功能。
将第三方库或插件整合到你的 Vue 项目中是非常有意义的。它使你可以对某些元素的操作进行更有效的控制。
总之,包装器组件特别是在较大的项目中,是使代码生成可重用性更好、更有条理和可预测的代码库的好方法。