文章目录
插槽的作用
组件的插槽也是为了让我们封装的组件更加具有扩展性
基本使用
展现组件标签内部的内容(包括标签)
插槽内容要在组件标签内部
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-slot</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<box-cs>
<h1>Something bad happened.</h1><!-- slot内容来源 -->
</box-cs>
<!-- slot展现组件内部的内容包括html节点 -->
</div>
<script>
Vue.component('box-cs',{
template:`<div>
<slot></slot>
</div>`
})
new Vue({
el:"#app"
})
</script>
</body>
</html>
默认内容
只会在组件内部没有提供内容的时候被渲染
<box-cs></box-cs>
Vue.component('box-cs',{
template:`<div>
box-cs
<slot>默认内容</slot>
</div>`
})
具名插槽 多个插槽使用
一个不带 name 的 出口会带有隐含的名字“default”。
任何没有被包裹在带有 v-slot 的 中的内容都会被视为默认插槽的内容。
在组件里面
v-slot 只能用于 template 标签
<template v-slot:header></template>
<template slot:header></template>
<div slot:header></div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-slot</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<base-layout>
<template v-slot:header>
<h1>header 插槽内容</h1>
</template>
<!-- <h1>默认插槽内容</h1> -->
<!-- 或 -->
<template v-slot:default>
<h1>默认插槽内容</h1>
</template>
<template v-slot:footer>
<h1>footer 插槽内容</h1>
</template>
</base-layout>
</div>
<script>
Vue.component('base-layout',{
template:`<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>`
})
new Vue({
el:"#app",
})
</script>
</body>
</html>
具名插槽的缩写
只能用于 template 标签
<div id="app">
<base-layout>
<template #header>
<h1>header 插槽内容</h1>
</template>
<template #footer="data"> <!--或 #footer="{data}"-->
<h1>footer 插槽内容</h1>
<!--data { title:'footer', msg:'footer is msg' }-->
{{data}}
</template>
</base-layout>
</div>
Vue.component('base-layout',{
data(){
return{
footer:{
title:'footer',
msg:'footer is msg'
}
}
},
template:`<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer" :footer="footer"></slot>
</footer>
</div>`
})
new Vue({
el:"#app",
})
作用域插槽
插槽默认内容 数据展示
<div id="app">
<base-layout>
</base-layout>
</div>
Vue.component('base-layout',{
data(){
return{
user:'userdata',
age:18
}
},
template:`<div>
<slot>{{user}}{{age}}</slot>
</div>`
})
new Vue({
el:"#app",
})
插槽模版传参
父组件替换插槽的标签,但是内容由子自己提供
<div id="app">
<base-layout>
<template v-slot:default="user">
<h1>默认插槽内容</h1>
<!-- user:{ "user": "userdata"} -->
{{ user.user }}
</template>
</base-layout>
</div>
Vue.component('base-layout',{
data(){
return{
user:'userdata',
age:18
}
},
template:`<div>
<slot :user="user"></slot>
</div>`
})
new Vue({
el:"#app",
})
多个参数
<div id="app">
<cpn></cpn>
<cpn>
<div slot-scope="slot">
{{slot.list.join(' -- ')}}
</div>
</cpn>
<cpn>
<!-- 2.5 以前必须用template标签 -->
<template v-slot:default="data">
{{data}}
</template>
</cpn>
<cpn>
<template v-slot="data">
{{data}}
</template>
</cpn>
</div>
<template id="tmp">
<div>
<!-- 默认列表 -->
<slot :list="plist,name">
<ul>
<li v-for="(item,i) in plist">{{item}}</li>
</ul>
</slot>
</div>
</template>
<script>
const cpn = {
template:'#tmp',
data(){
return {
plist:['aaa','xxx','javascript','java'],
name:"组件"
}
}
}
const app = new Vue({
data:{
},
components:{cpn},
methods:{}
}).$mount("#app")
</script>
被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用
只要出现多个插槽,请始终为所有的插槽使用完整的基于 的语法 即具名插槽写法
<div id="app">
<base-layout v-slot:default="data">
{{ data}}
</base-layout>
<!--或-->
<!--<base-layout v-slot="data">
{{ data}}
</base-layout>-->
</div>
Vue.component('base-layout',{
data(){
return{
user:'userdata',
age:18
}
},
template:`<div>
<slot :user="user,age"></slot>
</div>`
})
new Vue({
el:"#app",
})
解构插槽 Prop
<div id="app">
<base-layout>
<template v-slot:default="{user,age,sex={name:'ff'}}">
<h1>默认插槽内容</h1>
{{ user }} {{user}}
</template>
</base-layout>
</div>
Vue.component('base-layout',{
data(){
return{
user:'userdata',
age:18
}
},
template:`<div>
<slot :user="user,age"></slot>
</div>`
})
new Vue({
el:"#app",
})
动态插槽名
<div id="app">
<base-layout ff="header">
<template #[header]>
<h1>header 插槽内容</h1>
</template>
</base-layout>
</div>
Vue.component('base-layout',{
props:['ff'],
data(){
return{
user:'userdata',
age:18
}
},
template:`<div>
<header>
<slot :name="ff"></slot>
</header>
</div>`
})
new Vue({
el:"#app",
data:{
header:'header'
}
})