什么是插槽
简单理解就是“ 替换”,使用组件时能替换一些指定内容
比如:
- 有一些组件是一些通用的布局模板,每个展示的内容都不是固定,这时候就可以使用Vue提供的插槽功能
- 插槽的功能就是把组件的元素替换成传入的内容,内容可以是:文本、html、组件
注意:插槽的使用一般都在使用组件的时候
一、初次使用插槽
有一些组件是一些通用的布局模板,每个展示的内容都不是固定,这时候就可以使用Vue提供的插槽功能
插槽的功能就是把组件的元素替换成传入的内容,内容可以是:文本,html,其他组件
使用插槽主要就是使用元素 < slot />
第一步:在子组件的模板里定义个< slot />
<template id="component3">
<div>
<h1>哈哈</h1>
<slot> 我是默认值</slot>
</div>
</template>
第二步:在实例里把子组件component3注册上
const app = new Vue({
el: '#app',
components: {
'component1': {
template: "#component1"
},
'component2': {
template: "#component2"
},
'component3': {
template: "#component3"
}
}
})
第三步:使用组件
<!--不输入内容-->
<component1></component1>
<component3></component3>
提示:
组件里定义一个元素slot(可以有后备内容,就是默认值)
slot元素内容,可以有后备内容,就是默认值,当输入内容为空的,可以显示后备内容,
如果有输入内容就会slot替换成输入内容,后备内容就不会显示
示例 :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello vue</title>
</head>
<body style="background-color: darkcyan">
<div id="app">
<!--不输入内容-->
<component1></component1>
<!--输入文本-->
<component1>输入的内容</component1>
<!--输入html-->
<component1><div><a href="https://www.baidu.com/">百度一下,你就知道</a></div></component1>
<!--输入其他组件-->
<component1><component2/></component1>
<!--输入的内容,<slot></slot>会替换成输入的内容 -->
</div>
<!--组件里定义一个元素slot(可以有后备内容,就是默认值)
slot元素内容,可以有后备内容,就是默认值,当输入内容为空的,可以显示后备内容,
如果有输入内容就会slot替换成输入内容,后备内容就不会显示
-->
<template id="component1">
<div>
<h2>组件1</h2>
<slot>默认值</slot>
</div>
</template>
<template id="component2">
<div style="background-color: #c2d5d5">
<h2>组件2</h2>
</div>
</template>
</body>
<script src="../css/vue.js"></script>
<script>
/**
* 有一些组件是一些通用的布局模板,每个展示的内容都不是固定,这时候就可以使用Vue提供的插槽功能
* 插槽的功能就是把组件的<slot>元素替换成传入的内容,内容可以是:文本,html,其他组件
*/
const app = new Vue({
el: '#app',
components: {
'component1': {
template: "#component1"
},
'component2': {
template: "#component2"
}
}
})
</script>
</html>
二、具名插槽
之前说过,有一些组件是一些通用的布局模板,替换的内容每个都不一样,需要指定替换那个插槽位置,这时候就要给插槽取名来区分
2.1 在slot元素上使用attribute(属性):name
<slot name="name1"></slot>
2.2 怎么把内容放在制定的插槽位置?
使用指令v-slot和template
结合
<template v-slot:name1 >内容</template>
2.3 使用具名插槽
第一步:定义子组件模板
<template id="component1">
<div>
<div style="background-color: #b65757">
<h2>第1个插槽</h2>
<slot name="name1">第1个插槽</slot>
</div>
<div style="background-color: #7c9595">
<h2>第2个插槽</h2>
<slot name="name2">第2个插槽</slot>
</div>
</div>
</template>
第二步:在实例注册组件component1
<script>
const app = new Vue({
el: '#app',
components: {
'component1': {
template: "#component1"
}
}
})
</script>
第三步:在组件component1使用
<div id="app">
<!--不输入内容-->
<component1>
<template v-slot:name1 >
<h2>我是具名插槽1</h2>
</template>
<template v-slot:name2 >
<h2>我是具名插槽2</h2>
<div><a href="https://www.baidu.com/">百度一下,你就知道</a></div>
</template>
</component1>
</div>
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello vue</title>
</head>
<body style="background-color: darkcyan">
<div id="app">
<!--不输入内容-->
<component3>
<template v-slot:name1 >
<h2>我是具名插槽1</h2>
</template>
<template v-slot:name2 >
<h2>我是具名插槽2</h2>
<div><a href="https://www.baidu.com/">百度一下,你就知道</a></div>
</template>
</component3>
<component1></component1>
<!--输入文本-->
<component1>输入的内容</component1>
<!--输入html-->
<component1><div><a href="https://www.baidu.com/">百度一下,你就知道</a></div></component1>
<!--输入其他组件-->
<component1><component2/></component1>
<!--输入的内容,<slot></slot>会替换成输入的内容 -->
</div>
<!--组件里定义一个元素slot(可以有后备内容,就是默认值)
slot元素内容,可以有后备内容,就是默认值,当输入内容为空的,可以显示后备内容,
如果有输入内容就会slot替换成输入内容,后备内容就不会显示
-->
<template id="component1">
<div>
<h2>组件1</h2>
<slot>默认值</slot>
</div>
</template>
<template id="component3">
<div>
<div>
<h1>第1个插槽</h1>
<slot name="name1"> 第1个插槽</slot>
</div>
<div style="background-color: #7c9595">
<h2>第2个插槽</h2>
<slot name="name2">第2个插槽</slot>
</div>
</div>
</template>
<template id="component2">
<div style="background-color: #c2d5d5">
<h2>组件2</h2>
</div>
</template>
</body>
<script src="./vue.js"></script>
<script>
/**
* 有一些组件是一些通用的布局模板,每个展示的内容都不是固定,这时候就可以使用Vue提供的插槽功能
* 插槽的功能就是把组件的<slot>元素替换成传入的内容,内容可以是:文本,html,其他组件
*/
const app = new Vue({
el: '#app',
components: {
'component1': {
template: "#component1"
},
'component2': {
template: "#component2"
},
'component3': {
template: "#component3"
}
}
})
</script>
</html>
三、编译作用域和作用域插槽
3.1 编译作用域
1)Vue规则
说到编译作用域,先要明白一个Vue规则:
Vue规则:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的
2)举例说明
第一步:定义子组件模板
<template id="component1">
<div style="background-color: #b65757">
<h2 v-show="isShow">组件1</h2>
<slot>默认值</slot>
</div>
</template>
第二步:在实例上注册组件component1
<script>
const app = new Vue({
el: '#app',
data:{
isShow: true
},
components: {
'component1': {
template: "#component1",
data() {
return {
isShow: false
};
}
},
})
</script>
第三步:使用组件component1
<div id="app">
<component1>
<h3 v-show="isShow">hello</h3>
</component1>
</div>
展示效果
展示结果只有一个hello
因为编译作用域
- 使用组件component1时,isShow是app实例的data属性值
- 在组件component1里,isShow是component1的data属性值(所有模板里的h2就没有显示出来)
3.2 作用域插槽
1)什么是作用域插槽
作用域插槽,简单理解就是了父级能用子组件数据来控制展示内容,数据源是子组件,父组件只是选择哪个展示
2)举例说明使用
第一步:在组件模板的slot用绑定的方式 v-bind:属性名=data值
<template id="component2">
<div style="background-color: #7c9595">
<slot>默认值1</slot>
<slot name="name1"
v-bind:message="message"
v-bind:message1="message1"
>
默认值2
</slot>
</div>
</template>
第二步:在实例上注册组件component2,return的data值是message和message1
<script>
const app = new Vue({
el: '#app',
components: {
'component2': {
template: "#component2",
data() {
return {
message: "我是子组件的内容",
message1: "message1"
};
}
}
}
})
</script>
第三步:组件上使用
在使用组件的时候,在template用v-slot:name1(具名插槽名字)=“slotProps”,内容就可以直接使用:
slotProps.属性(这个属性就是slot用 v-bind:属性名=data值),来获取到子组件的数据了
- {{slotProps.message}}
- {{slotProps.message1}}
<div id="app">
<component2>
<template v-slot:name1="slotProps" >
<h2>{{slotProps.message}}</h2>
<h2>{{slotProps.message1}}</h2>
</template>
</component2>
</div>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aBbaXkvs-1612841995123)(vue笔记03_files/1.jpg)]
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello Vue</title>
</head>
<body>
<div id="app">
<component2>
<template v-slot:name1="slotProps" >
<h2>{{slotProps.message}}</h2>
<h2>{{slotProps.message1}}</h2>
</template>
</component2>
</div>
<template id="component2">
<div style="background-color: #CCCCCC">
<slot>默认值1</slot>
<slot name="name1"
v-bind:message="message"
v-bind:message1="message1"
>
默认值2
</slot>
</div>
</template>
</body>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#app',
components: {
'component2': {
template: "#component2",
data() {
return {
message: "我是子组件的内容",
message1: "message1"
};
}
}
}
})
</script>
</script>
</html>
四、动态插槽名
动态插槽名就是通过data的属性值来控制插槽名,当属性值修改时,也会跟着改变插槽的替换位置
注意,不是cli构造的工程,使用驼峰命名会有问题,不能生效
例子说明使用
第一步:定义组件模板
<template id="component1">
<div>
<div style="background-color: #b65757">
<slot name="name1">第1个插槽</slot>
</div>
<div style="background-color: #7c9595">
<slot name="name2">第2个插槽</slot>
</div>
</div>
</template>
第二步:实例注册组件component1
<script>
const app = new Vue({
el: '#app',
data:{
slotname: 'name1'
},
components: {
'component1': {
template: "#component1"
}
}
})
</script>
第三步:使用组件
<div id="app">
<component1>
<template v-slot:[slotname] >
<h2>我是动态插槽</h2>
</template>
</component1>
</div>
在控制台我们把把 app.$data.slotname=‘name2’
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CWu6DbUT-1612841995125)(vue笔记03_files/2.jpg)]
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello Vue</title>
</head>
<body>
<div id="app">
<component1>
<template v-slot:[slotname] >
<h2>我是动态插槽</h2>
</template>
</component1>
</div>
<template id="component1">
<div>
<div style="background-color: #b65757">
<slot name="name1">第1个插槽</slot>
</div>
<div style="background-color: #7c9595">
<slot name="name2">第2个插槽</slot>
</div>
</div>
</template>
</body>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data:{
slotname: 'name1'
},
components: {
'component1': {
template: "#component1"
}
}
})
</script>
</html>
五、具名插槽缩写
具名插槽缩写,用#替换成v-slot
注意没有插槽名字的时候要用:#default
<div id="app">
<component1>
<template v-slot:name1 >
<h2>我是具名插槽1</h2>
</template>
</component1>
<component1>
<!--具名插槽缩写,用#替换成v-slot-->
<template #name1 >
<h2>我是具名插槽2</h2>
</template>
</component1>
</div>