No more than code.
VUE SLOT - 插槽
Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 <slot>
元素作为承载分发内容的出口。
2.6.0 更新后的语法
// 基础用法
<button type="submit">
<slot></slot>
</button>
// 插槽默认内容-Submit
<button type="submit">
<slot>Submit</slot>
</button>
具名插槽
// 不带 name 的 <slot> 出口会带有隐含的名字“default”
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
// 向具名插槽提供内容
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
// 现在 <template> 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 <template> 中的内容都会被视为默认插槽的内容
注意 v-slot 只能添加在
<template>
上 (只有一种例外情况:独占默认插槽的缩写语法)
作用域插槽
用于子级作用域向父级作用域传值
// 子级:绑定在 <slot> 元素上的 attribute 被称为插槽 prop
<span>
<slot v-bind:user="user">
</slot>
</span>
// 父级作用域中,可以使用带值的 v-slot 来定义提供的插槽 prop 的名字:
<current-user>
<template v-slot:default="slotProps">
</template>
</current-user>
独占默认插槽的缩写语法
在上述情况下,当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。这样我们就可以把 v-slot 直接用在组件上
<current-user v-slot:default="slotProps">
</current-user>
注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确。只要出现多个插槽,请始终为所有的插槽使用完整的基于
<template>
的语法:
<current-user>
<template v-slot:default="slotProps">
</template>
<template v-slot:other="otherSlotProps">
...
</template>
</current-user>
解构插槽 Prop
<current-user v-slot="{ user }">
</current-user>
// 将 user 重命名为 person:
<current-user v-slot="{ user: person }">
</current-user>
// 后备内容,用于插槽 prop 是 undefined 的情形:
<current-user v-slot="{ user = { firstName: 'Guest' } }">
</current-user>
具名插槽的缩写
v-slot:
等价于 #
,例如 v-slot:header
可以被重写为 #header
,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:
<!-- 这样会触发一个警告 -->
<current-user #="{ user }">
</current-user>
// 如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:
<current-user #default="{ user }">
</current-user>
自 2.6.0 起被废弃的语法
<base-layout>
<template slot="header">
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template slot="footer">
<p>Here's some contact info</p>
</template>
</base-layout>
<slot-example>
<template slot-scope="slotProps">
</template>
</slot-example>
透传
// 组件
<template>
<el-button
v-bind="customizedAttrs"
v-on="$listeners"
>
<slot />
</el-button>
</template>
<script>
export default {
name: "MyButton",inheritAttrs:false,
props: {
size: {
type: String,
default: "medium",
},
},
computed: {
customizedAttrs() {
return {
size: "medium",
// 支持传过来的size覆盖默认的size
...this.$attrs,
};
},
},
};
</script>
// 使用
<template>
<my-button
type="success"
round
autofocus
@click="handleClick"
/>
</template>