插槽的基本用法
插槽的意义:
1.给组件预留空间。
2.让封装的组件更加具有扩展性。
3.让使用组件的人不改变组件代码,但是能自己决定组件内部的一些内容。
实际用例:京东的导航栏
对比2个导航栏会发现,第二个导航栏多了一个分类。难道第二个导航栏需要完成重做吗?不需要的,可以在第一个导航栏里那个位置加一个插槽,需要的时候就把这个分类的标签插进去并且显示,不需要的时候就不使用插槽。一个组件多种复用。
基本用法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn><button>你好</button></cpn>
<cpn>
<p>很高兴见到你</p>
</cpn>
</div>
</body>
<template id="cpn">
<div>
<h1>Shu</h1>
<h1>Wen</h1>
<slot><button>天气不错</button></slot>
</div>
</template>
<script>
const app = new Vue({
el:"#app",
data:{
message:'Shu',
},
components:{
cpn:{
template:'#cpn',
}
}
})
</script>
</html>
具名插槽
一个组件中有多个插槽时,在用组件时,解决用哪一个插槽的问题。
这里注意具体使用哪个插槽时,一定要写在cpn标签的里面的标签,也就是使用插槽的标签,而不是写在cpn组件的标签上。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn><button slot="aa">返回</button></cpn>
<cpn><p slot="bb">请输入</p></cpn>
<cpn><button slot="cc">进一步</button></cpn>
</div>
</body>
<template id="cpn">
<div>
<h1>Shu</h1>
<h1>Wen</h1>
<slot name="aa"><button>前</button></slot>
<slot name="bb"><button>中</button></slot>
<slot name="cc"><button>后</button></slot>
</div>
</template>
<script>
const app = new Vue({
el:"#app",
data:{
message:'Shu',
},
components:{
cpn:{
template:'#cpn',
}
}
})
</script>
</html>
插槽作用域
template定义的组件,组件的作用域在这里面被组件控制。外部html的主体由app控制。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<cpn v-show="isShow"></cpn>
//这里的isShow是app data里面的
</div>
<template id="cpn">
<div>
<h2>我是子组件</h2>
<p>我是内容, 哈哈哈</p>
<button v-show="isShow">按钮</button>
//这里的isShow是cpn data里面的
<slot></slot>
</div>
</template>
<script>
const app = new Vue({
el: '#app',
data: {
isShow: true
},
components: {
cpn: {
template: '#cpn',
data() {
return {
isShow: false
}
}
},
}
})
</script>
</body>
</html>
获取插槽子组件的数据
父组件替换插槽的标签,但是插槽的内容(数据data)是由子组件决定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn>
<!--目的是获取子组件中的pLanguages-->
<template v-slot="slot">
<!--<span v-for="item in slot.data"> - {{item}}</span>-->
<span>{{slot.data.join(' - ')}}</span>
</template>
</cpn>
<cpn>
<!--目的是获取子组件中的pLanguages-->
<template v-slot="slot">
<!--<span v-for="item in slot.data">{{item}} * </span>-->
<span>{{slot.data.join(' * ')}}</span>
</template>
</cpn>
<!--<cpn></cpn>-->
</div>
<template id="cpn">
<div>
<slot :data="pLanguages">
<ul>
<li v-for="item in pLanguages">{{item}}</li>
</ul>
</slot>
</div>
</template>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn',
data() {
return {
pLanguages: ['海贼王', '火影', '死神', '龙珠', '妖尾']
}
}
}
}
})
</script>
</body>
</html>