详解vue 2.6 中 slot 的新用法

2020-06-14 06:28:07易采站长站整理


<!-- 使用 my-modal.vue -->
<template>
<my-modal>
<template #header>
<h5>Awesome Interruption!</h5>
</template>
<template #body>
<p>大家加油!</p>
</template>
<template #footer="{closeModal}">
<button @click="closeModal">
点我可以关闭烦人的对话框
</button>
</template>
</my-modal>
</template>

无渲染组件

最后,可以利用你所知道的关于使用插槽来传递可重用函数的知识,并剥离所有HTML,只使用插槽。这就是无渲染组件的本质:一个只提供函数而不包含任何HTML的组件。

使组件真正无渲染可能有点棘手,因为需要编写 render 函数而不是使用模板来消除对根元素的依赖,但它可能并不总是必要的。 来看看一个先使用模板的简单示例:


<template>
<transition name="fade" v-bind="$attrs" v-on="$listeners">
<slot></slot>
</transition>
</template>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>

这是一个无渲染组件的奇怪例子,因为它甚至没有任何JavaScript。这主要是因为我们正在创建一个内置无渲染函数的预配置可重用版本: transition 。

是的,Vue有内置的无渲染组件。这个特殊的例子取自Cristi Jora的一篇关于 可重用transition 的文章,展示了一种创建无渲染组件的简单方法,该组件可以标准化整个应用程序中使用的 transition 。

对于我们的另一个示例,我们将创建一个组件来处理切换 Promise 的不同状态中显示的内容: pending、resolved 和 failed。这是一种常见的模式,虽然它不需要很多代码,但是如果没有为了可重用性而提取逻辑,它会使很多组件变得混乱。


<!-- promised.vue -->
<template>
<span>
<slot name="rejected" v-if="error" :error="error"></slot>
<slot name="resolved" v-else-if="resolved" :data="data"></slot>
<slot name="pending" v-else></slot>
</span>
</template>
<script>
export default {
props: {
promise: Promise
},
data: () => ({
resolved: false,
data: null,
error: null
}),
watch: {
promise: {
handler (promise) {
this.resolved = false
this.error = null
if (!promise) {
this.data = null
return
}
promise.then(data => {
this.data = data
this.resolved = true
})
.catch(err => {