官网 https://cn.vuejs.org/v2/guide/components-slots.html
slot 槽口/插槽
插槽用来混合父组件与子组件自己的模板(就是可以在组件被调用的时候向其内部插入新的dom节点)
组件的内容就是标签的innerHTML。vue.js里使用Slot(插槽)分发内容。
props用来处理标签的属性 ,slot用来处理标签的内容。 将父组件的内容(DOM)放到子组件指定的位置叫作内容分发。
思考:
组件如果调用的时候使用双标签 那么我们在他的开关标签中能否插入新的内容?
答:默认情况下是不行的
那如果我就要它显示呢????????????? 答:Slot
一、先来父子组件吧
① father.vue ② son.vue
<template>
<div>
father组件
<Son>
这个h1是不会显示的
<h1>我是h1标签</h1>
</Son>
</div>
</template>
<script>
import Son from "./Son.vue"
export default {
components:{
Son
}
}
</script>
二、Slot
2-1、单个插槽(基本插槽)
就是在你想插入新内容的组件中 放置一个<slot></slot> 外部的内容就会显示在slot插入的位置
比如上面写的h1标签内容没显示?那我可以这样写:
在son.vue 里
<template>
<div>
Son.vue 子组件
<!--插槽-->
<slot></slot>
</div>
</template>
<script>
export default {
}
</script>
大家会发现 上面的槽口只有一个,但是外部插入的所有内容都在这一个上面进行显示 后期不好管理
所以看具名槽口
2-2、具名插槽(多个插槽需要使用名字)
如果父级给子级传来了好多DOM(HTML元素),而且需要把不同的DOM放在子组件不同位置时,就需要给slot起名字,这就是具名插槽。slot元素可以用一个特殊的属性name 来配置如何分发内容。
① 格式:定义槽口的时候 使用name创建槽口的名字
<slot name="插槽名"></slot>
<template>
<div>
Son.vue 子组件
<!--具名插槽-->
<slot name="tian"></slot>
<slot name="xiao"></slot>
<slot name="hello"></slot>
</div>
</template>
<script>
export default {
}
</script>
父组件里 插入的时候需要指定往那个槽口中插入 使用slot属性
//插入的时候需要指定往那个槽口中插入 使用slot属性
<template>
<div>
father组件
<Son>
<h1 slot="tian">我是h1标签----01</h1>
<h1>我是h1标签----02</h1>
<h1>我是h1标签----03</h1>
<h1>我是h1标签----04</h1>
<h1 slot="tian">我是h1标签----05</h1>
<!--格式: v-slot:插槽名称 -->
<template v-slot:xiao> //v-slot是从2.6.0+时期开始使用的
<h4>我是h4标签</h4>
</template>
<!--简写格式: #插槽名称 -->
<template #hello> //可以简写用 # 即可
<h5>我是h5标签</h5>
</template>
</Son>
</div>
</template>
<script>
import Son from "./Son.vue"
export default {
components:{
Son
}
}
</script>
2-3、作用域插槽
父组件模板的内容在父组件作用域内(父组件对应的对象的作用域)编译;子组件模板的内容在子组件作用域内编译
作用域插槽就是父组件可以接收子组件传递的参数
子组件里
<template>
<div>
<h1>{{msg}}</h1>
<slot :name="tian" :txt1="1" :txt2="2"></slot>
<slot :str="strData" :name="default"></slot>
</div>
</template>
<script>
export default {
data(){
return {
msg:"我是子组件",
strData:{
name:"小黑",
job:"学生"
}
}
}
}
</script>
父组件里
<template>
<div>
father组件
<Son>
<template #tian="props"> //2.6.0+后的方式
<div>txt1:{{ props.txt1 }}</div>
<div>txt2:{{ props.txt2 }}</div>
</template>
<div slot="tian" slot-scope="props"> //这种方式是2.6.0之前的方式(vue3已经弃了)
<div>txt1:{{ props.txt1 }}</div>
<div>txt2:{{ props.txt2 }}</div>
</div>
<!-- v-slot:插槽名称="props" 也可以解构v-slot:插槽名称="{props}" -->
<template v-slot:default="props">
{{props.str.job}}
</template>
<!-- 这个#tian也可以用变量(动态插槽名) -->
<template #[name]="props">
<div>txt1:{{ props.txt1 }}</div>
<div>txt2:{{ props.txt2 }}</div>
</template>
</Son>
</div>
</template>
<script>
import Son from "./Son.vue"
export default {
components:{
Son
},
data() {
return {
name:'tian'
}
}
}
</script>