Vue 实现了一套内容分发的 API,将 <slot>
元素作为承载分发内容的出口。
- 什么是插槽?
在vue中我们经常把公共的部分抽取出来单独打包成一个组件,但是在使用这些组件的时候,我们会遇到一些内容上的区别。我们希望在这些组件上添加一些不一样内容,这时候我们就需要使用到插槽来分发内容。
// 父组件
<template>
<div>
<div>大家好我是父组件</div>
<myslot>
<p>测试一下吧内容写在这里了能否显示</p>
</myslot>
</div>
</template>
<script>
import myslot from './myslot';
export default {
components: {
myslot
}
}
</script>
<style>
</style>
// 子组件
<template>
<div>
<div>我是子组件</div>
<p>测试一下slot的能否获取到父组件传过来的模版</p>
<slot>后备内容</slot> <!-- 如果子组件中没有内容则不会代插槽中的默认内容(后备内容) -->
</div>
</template>
<script>
</script>
<style>
</style>
<!--
测试结果:
大家好我是父组件
我是子组件
测试一下slot的能否获取到父组件传过来的模版
测试一下吧内容写在这里了能否显示
-->
总结一下
1.父组件在引用子组件时希望向子组价传递模板内容
<p>测试一下吧内容写在这里了能否显示</p>
2.子组件让父组件传过来的模板内容在所在的位置显示
3.子组件中的
<slot>
就是一个槽,可以接收父组件传过来的模板内容,<slot>
元素自身将被替换4.
<myslot></myslot>
组件没有包含一个<slot>
元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃
- 插槽的作用?
让用户更好的扩展组件,更好的去复用组件以及对其进行定制化处理。
- 插槽的分类?
- 默认插槽
后备内容的特点,
注意: 默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确:
- 具名插槽
<slot>
元素有一个特殊的 attribute:name
。这个 attribute 可以用来定义额外的插槽.一个不带
name
的<slot>
出口会带有隐含的名字“default”。
<template>
<div class="container">
<header>
<slot name="left"></slot> <!-- 插在对应的header中 -->
</header>
<main>
<slot></slot> <!-- 插在对应的default中 -->
</main>
<footer>
<slot name="right"></slot> <!-- 插在对应的footer中 -->
</footer>
</div>
</template>
向具名插槽提供内容的时候,我们可以在一个标签上使用v-slot指令提供名称。
<cpn><template v-slot:left><button type="button">返回</button></template></cpn>
<cpn><template><span>标题</span></template></template></cpn>
<!-- 或者 -->
<cpn><template v-slot:dafault><span>标题</span></template></cpn>
<cpn><template v-slot:left><span v-slot:right>更多</span></template></cpn>
<left>...</left>
<template></template>
<right>...</right>
v-slot
只能添加在 <template>
上, 同样是传递给子组件中不带 name
的 <slot>
注意: v-slot
只能添加在 <template>
上 具名插槽在书写的时候可以使用缩写,v-slot
用#来代替
- 作用域插槽
vue官方文档给出 父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的.
为了能使得父组件中也能显示子组件中和子组件中的数据绑定的内容,需要在子组件中指定数据,并在父组件中对象形式引用即可。
//子组件
<template id="cpn">
<slot :data="languages">
<ul>
<li v-for="item in languages">{{item}}</li>
</ul>
</slot>
</template>
//父组件
<cpn>
<template v-slot="slot">
<span>{{slot.data.join(' * ')}}</span>
</template>
</cpn>
// 子组件数据
data() {
return {
languages: ['javascipt','mysql','java','vue','c#','c++','go']
}
}
- 什么是编译作用域?
vue官方文档给出 父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的.