1. 将 prop 限制为类型列表
在 prop 定义中使用 validator
选项,你可以将 prop 限制为一组特定的值:
export default {
name: 'Image',
props: {
src: {
type: String,
},
style: {
type: String,
validator: s => ['square', 'rounded'].includes(s)
}
}
};
复制代码
这个 validator 函数接受一个 prop,返回 true 或 false。当你需要比布尔值允许的更多选项时,也可以使用它。按钮类型或警报类型(信息、成功、危险、警告)是一些比较常见的用途。
2. 默认内容和扩展点
Vue 中的slot可以具有默认内容,这使你可以制作更易于使用的组件:
<button class="button" @click="$emit('click')">
<slot>
<!-- 如果没有提供slot则使用 -->
Click me
</slot>
</button>
复制代码
基本上你可以获取组件的任何部分,将其包装在一个slot中,然后你可以使用你想要的任何内容覆盖该组件的该部分。默认情况下,它仍然会像往常一样工作,你还可以有更多选择:
<template>
<button class="button" @click="$emit('click')">
<!-- 一开始在 slot 标签中添加什么都不做 -->
<!-- 我们可以通过向 slot 提供内容来覆盖它 -->
<slot>
<div class="formatting">
{
{ text }}
</div>
</slot>
</button>
</template>
复制代码
现在你可以以多种不同的方式使用该组件。简单的默认方式或你自己的自定义方式:
<!-- 使用组件的默认功能 -->
<ButtonWithExtensionPoint text="Formatted text" />
<!-- 使用扩展点创建自定义行为 -->
<ButtonWithExtensionPoint>
<div class="different-formatting">
在这里做一些不同的事情
</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. 单作用域 slot 的简写(不需要模板标签!)
Scoped slot 比较有趣,但为了使用它们,你也必须使用很多template
标签。
然而有一个速记可以让我们摆脱它,但前提是我们使用单个作用域slot。
可以不用这样写:
<DataTable>
<template #header="tableAttributes">
<TableHeader v-bind="tableAttributes" />
</template>
</DataTable>
复制代码
我们可以这样写:
<DataTable #header="tableAttributes">
<TableHeader v-bind="tableAttributes" />
</DataTable>
复制代码
这样更简单、直接。
6. 有条件地渲染slot
每个 Vue 组件都有一个特殊的 $slots 对象,其中包含所有slot。 默认slot具有默认键,名字命名的slot都使用它们的名称作为键:
const $slots = {
default: <default slot>,
icon: <icon slot>,
button: <button slot>,
};
复制代码
但是这个$slots
对象只有应用于组件的slot,而不是每个定义的slot。
以这个定义了几个slot的组件为例,包括几个命名的slot:
<!-- Slots.vue -->
<template>
<div>
<h2>这里是一些slots</h2>
<slot />
<slot name="second" />
<slot name="third" />
</div>
</template>
复制代码
如果我们只对组件应用一个slot,则只有该slot会出现在我们的$slots
对象中:
<template>
<Slots>
<template #second>
这将应用于第二个slot
</template>
</Slots>
</template>
复制代码
$slots = { second: <vnode> }
复制代码
我们可以在我们的组件中使用它来检测哪些slot已应用于组件,例如,通过隐藏slot的包装元素:\
<template>
<div>
<h2>一个包裹的slot</h2>
<div v-if="$slots.default" class="styles">
<slot />
</div>
</div>
</template>
复制代码
现在div
,应用样式的包装器只有在我们实际用某些东西填充该slot时才会呈现。
如果我们不使用v-if
,div
如果我们没有slot,我们最终会得到一个空的和不必要的。根据所div
具有的样式,这可能会弄乱我们的布局并使事情看起来很奇怪。
为什么我们希望能够有条件地渲染slot呢?
使用条件slot主要有以下三个原因:
- 使用 wrapper
div
来添加默认样式时 - slot是空的 <