什么是插槽
在构建页面过程中一般会把用的比较多的公共的部分抽取出来作为一个单独的组件,但是在实际使用这个组件的时候却又不能完全的满足需求,在这个组件中添加一点东西,这时候就需要用到插槽来分发内容。
示例
下面看一个例子 写一个父组件: test.vue
<template>
<div>
<div>大家好我是父组件</div>
<myslot>
<p>测试一下吧内容写在这里了能否显示</p>
</myslot>
</div>
</template>
<script>
import myslot from './myslot';
export default {
components: {
myslot
}
}
</script>
<style>
</style>
写一个子组件:myslot.vue
<template>
<div>
<div>我是子组件</div>
</div>
</template>
<script>
</script>
<style>
运行代码,发现,最终渲染的效果是
大家好我是父组件
我是子组件
那如果想实现显示父组件中p标签的内容怎么办 修改子组件:myslot.vue
<template>
<div>
<div>我是子组件</div>
<p>现在测试一下slot</p>
<slot></slot>
</div>
</template>
<script>
</script>
<style>
</style>
运行代码,可以看到以下效果
大家好我是父组件
我是子组件
现在测试一下slot
测试一下吧内容写在这里了能否显示
经常需要向一个组件传递内容 Vue 自定义的 <slot>
元素让这变得非常简单 只要在需要的地方加入插槽就行了结合上面的例子来理解就是这样的:
1.父组件在引用子组件时希望向子组价传递模板内容<p>
测试一下吧内容写在这里了能否显示</p>
2.子组件让父组件传过来的模板内容在所在的位置显示
3.子组件中的<slot>
就是一个槽,可以接收父组件传过来的模板内容,<slot>
元素自身将被替换
4.<myslot></myslot>
组件没有包含一个 <slot>
元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃
插槽的作用
让用户可以拓展组件,去更好地复用组件和对其做定制化处理
插槽的分类
1.普通插槽
在子组件中使用 <slot></slot>
占位,就可以在组件的标签中输入内容,放到插槽位置显示
<组件名>
<h1>
这里的内容会呈现在插槽中</h1>
</组件名>
2.具名插槽
<slot name='aa'></slot>
使用name属性给插槽命名 使用<template
v-slot:aa></template>
标签和v-slot
指令来使用
示例
<template>
<div class="container">
<header>
<!-- 我们希望把页头放这里 -->
</header>
<main>
<!-- 我们希望把主要内容放这里 -->
</main>
<footer>
<!-- 我们希望把页脚放这里 -->
</footer>
</div>
</template>
对于这样的情况,<slot>
元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽:
<template>
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
一个不带 name 的 出口会带有隐含的名字“default”。 父组件在向具名插槽提供内容的时候,我们可以在一个 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:
<template>
<myslot>
<div>大家好我是父组件</div>
<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 footer info</p>
</template>
</myslot>
</template>
<script>
import myslot from './myslot';
export default {
components: {
myslot
}
}
</script>
<style>
</style>
最终的渲染结果
Here might be a page title
大家好我是父组件
A paragraph for the main content.And another one.
Here’s footer info
父组件中会向子组件中具名传递对应的模板内容,而没有指定名字的模板内容会传递给子组件中不带 name 的 <slot>
如果父组件中
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
同样是传递给子组件中不带 name 的 <slot>
注意:
v-slot 只能添加在
<template>
上 具名插槽在书写的时候可以使用缩写,v-slot用#来代替
<template>
<myslot>
<div>大家好我是父组件</div>
<template #header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template #footer>
<p>Here's footer info</p>
</template>
</myslot>
</template>
<script>
import myslot from './myslot';
export default {
components: {
myslot
}
}
</script>
3.动态插槽
<slot name='aa'></slot>
使用name属性给插槽命名
使用 <template v-slot:[变量]></template>
v-slot指令的值使用[]包裹起来,就可以解析里面的变量
示例:
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>