学习成为一个更好的Vue开发者并不总是关于那些需要花时间和精力才能掌握的大概念。掌握一些技巧和窍门,可以让我们的编程生活变得更容易--没有大量重复的工作。
在用 Vue 开发的这几年里,我学到了很多有用的技巧。有些很取巧,有些几乎每天都在用,有些则更高级--但它们都很有用。
1. 将一个 prop 限制在一个类型的列表中
使用 prop 定义中的 validator
选项,可以将一个 prop 类型限制在一组特定的值中。
export default {
name: 'Image',
props: {
src: {
type: String,
},
style: {
type: String,
validator: s => ['square', 'rounded'].includes(s)
}
}
};
复制代码
这个验证函数接受一个prop,如果prop有效或无效,则返回true
或false
。
当单单传入的 true 或 false 来控制某些条件不能满足需求时,我通常使用这个方法来做。
按钮类型或警告类型(信息、成功、危险、警告)是最常见的用法、、。颜色也是一个很好的用途。
2. 默认内容和扩展点
Vue中的槽可以有默认的内容,这使我们可以制作出更容易使用的组件。
<button class="button" @click="$emit('click')">
<slot>
<!-- Used if no slot is provided -->
Click me
</slot>
</button>
复制代码
我最喜欢使用默认槽,就是用它们来创建扩展点。
我们可以取组件的任何部分,将其封装在一个插槽中,在外面我们可以用想要的任何内容覆盖组件的该部分。默认情况下,它仍然会按照原来的方式工作,但这样做会有了更多的选项
<template>
<button class="button" @click="$emit('click')">
<slot>
<div class="formatting">
{
{ text }}
</div>
</slot>
</button>
</template>
复制代码
现在我们可以用许多不同的方式使用这个组件。简单的、默认的方式,或者自定义的方式。
<!-- Uses default functionality of the component -->
<ButtonWithExtensionPoint text="Formatted text" />
<ButtonWithExtensionPoint>
<div class="different-formatting">
Do something a little different here
</div>
</ButtonWithExtensionPoint>
复制代码
3. 使用引号来监听嵌套属性
你可能不知道这一点,我们可以通过使用引号轻松地直接监听嵌套值:
watch {
'$route.query.id'() {
// ...
}
}
复制代码
4. 知道何时使用v-if
(以及何时避免使用)
与其使用v-if
,有时使用v-show
来代替,会有更高的性能。
<ComplicatedChart v-show="chartEnabled" />
复制代码
当v-if
被打开或关闭时,它将创建并完全销毁该元素。相反,v-show
将创建该元素并将其留在那里,通过设置其样式为display: none
来隐藏它。
如果你要切换的组件的渲染成本很高,那么这样做会更有效率。
反过来说,如果不需要立即执行昂贵的组件件,可以使用v-if
,这样它就会跳过渲染它,而使页面的加载速度更快一些。
5. 单个作用域插槽的简写(不需要 template 标签)
限定范围的插槽非常有趣,但为了使用它们,您还必须使用许多模板标记。
幸运的是,有一个简写可以让我们摆脱它,但只有在我们使用单个作用域槽的情况下。
普通写法:
<DataTable>
<template #header="tableAttributes">
<TableHeader v-bind="tableAttributes" />
</template>
</DataTable>
复制代码
不使用 template
:
<DataTable #header="tableAttributes">
<TableHeader v-bind="tableAttributes" />
</DataTable>
复制代码
简单、直截了当,令人赞叹不已。
6. 有条件地渲染插槽
我们先来看如何做,然后在讨论为什么想隐藏插槽。
每个Vue组件都有一个特殊的$slots
对象,里面有你所有的插槽。默认槽的键是default
,任何被命名的槽都使用其名称作为键。
const $slots = {
default: <default slot>,
icon: <icon slot>,
button: <button slot>,
};
复制代码
但这个$slots
对象只有适用于该组件的插槽,而不是每一个定义的插槽。
拿这个定义了几个插槽的组件来说,包括几个命名的插槽。
<!-- Slots.vue -->
<template>
<div>
<h2>Here are some slots</h2>
<slot />
<slot name="second" />
<slot name="third" />
</div>
</template>
复制代码
如果我们只对组件应用一个插槽,那么只有那个插槽会显示在我们的$slots
对象中。
<template>
<Slots>
<template #second>
This will be applied to the second slot.
</template>
</Slots>
</template>
复制代码
$slots = { second: <vnode> }
复制代码
我们可以在我们的组件中使用这一点来检测哪些插槽已经被应用到组件中,例如,通过隐藏插槽的包装元素。
<template>
<div>
<h2>A wrapped slot</h2>
<div v-if="$slots.default" class="styles">
<slot />
</div>
</div>
</template>
复制代码
现在,应用样式的包装器div
只有在我们用某些东西填充这个插槽时才会被渲染。
如果不使用v-if
,那么如果没有插槽,就会得到一个空的不必要的div
。根据div
的样式,这可能会打乱我们的布局,让界面看起来很奇怪。
那么,为什么我们希望能够有条件地渲染插槽呢?
使用条件插槽的主要原因有三个:
- 当使用封装的
div
来添加默认样式时 - 插槽是空的
- 如果我们将默认内容与嵌套槽相结合
例如,当我们在添加默认样