文章目录
一,介绍插槽
1.什么是插槽?
理解
插槽就是在子组件中用<slot></slot>
挖个坑,坑内内容由父组件来决定
子组件提供给父组件使用一个占位符slot,
父组件可在slot中填充任何模板代码,如 HTML、组件等,
填充的内容会替换子组件中的<slot></slot>标签。
作用
提高组件的重用能力
步骤
子组件:在指定位置留下<slot></slot>
父组件:引入,注册子组件,在子组件的同名占位符中写东西(如 HTML、组件等)
区分父子组件
(*换言之:使用了<slot></slot>
或者<slot name-"xxx"></slot>
的组件是子组件,使用了子组件名如<son>这里写准备插入子组件的内容</son>
的是父组件)
这是区分插槽中的父子组件的标志,
对插槽的再次理解
即父组件把准备插入子组件中的内容放在子组件占位符中,
(如<son>插入内容</son>
,在实际开发中插入内容可以是好几层标签,十几到几十行或者更多行代码),
而子组件预留一个槽位,在需要放置插入内容的位置留下<slot></slot>
,代表此处即将被放入父组件插入的内容
2.插槽的种类
- 匿名插槽:没给插槽slot起名字,也叫默认插槽
- 具名插槽:给slot起名字(定义具名插槽:使用到name特性)
- 作用域插槽:本质是携带信息的匿名插槽
二.匿名插槽,具名插槽和作用域插槽的定义和使用:在网页和在项目中的使用示例
1.匿名插槽
1.1.匿名插槽定义和用法
略 详见上面的插槽介绍
1.2.在网页使用匿名插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
h3{
color:blueviolet
}
</style>
</head>
<body>
<!--默认存在一个根组件,是所有组件的父组件 -->
<div id="app">
<niming>匿名</niming>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//全局注册子组件niming
Vue.component("niming",{
template:`<div>我是<h3><slot></slot></h3>插槽</div>`
});
new Vue({
el:"#app"
})
</script>
</html>
1.3.vue项目中使用匿名插槽
(正确单词应该是component不是componment,下同)
- 父组件:FatherComponment.vue
<template>
<div>
<son-componment>
<h3>匿名</h3>
</son-componment>
</div>
</template>
<script>
import SonComponment from './SonComponment.vue';
export default {
components: {SonComponment},
};
</script>
<style scoped>
</style>
- 子组件SonComponment.vue
<template>
<div>
<!-- 我是<h3><slot></slot></h3>插槽 -->
我是<slot></slot>插槽
</div>
</template>
<script>
export default {
};
</script>
<style scoped>
h3{
color:blueviolet
}
</style>
- 在router/index.js中引入父组件
import Vue from 'vue'
import VueRouter from 'vue-router'
import Father from "../views/FatherComponment"
Vue.use(VueRouter)
const routes = [{
path: '/',
component: Father
}
]
const router = new VueRouter({
routes
});
export default router
2.具名插槽
2.1.具名插槽的定义和用法
- 形式
子组件把多个插槽放置在不同地方,父组件根据插槽名字填充对应内容 - v-slot指令
在向具名插槽提供内容的时候,我们可以在template元素上使用v-slot指令, 并以参数的形式提供其名称
(一般是在vue项目中使用,如父组件中使用<template v-slot="juming">插入子组件的内容</template>
) - name特性
slot元素有一个特殊的特性:name ,这个特性可以用来定义额外的插槽
(,而子组件使用<slot name="juming"></slot>
来放置来自父组件的内容)
2.2.在网页中使用具名插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
h3{
color:blueviolet
}
</style>
</head>
<body>
<!--默认存在一个根组件,是所有组件的父组件 -->
<div id="app">
<!-- 匿名插槽 -->
<niming>匿名</niming>
<!-- 具名插槽 -->
<juming>
<div>商品参数</div>
<div><img src="https://ftp.bmp.ovh/imgs/2021/05/b86a125cadd68fb3.png" alt=""></div>
<div slot="toubu">头部</div>
<div slot="weibu">尾部</div>
</juming>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//全局注册子组件niming
Vue.component("niming",{
template:`<div>我是<h3><slot></slot></h3>插槽</div>`
});
//全局注册子组件juming
Vue.component("juming",{
template:`<div>
<header>
<slot name="toubu"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="weibu"></slot>
</footer>
</div>`
});
new Vue({
el:"#app"
})
</script>
</html>
此例中,父组件中img图片本来放在最上面,渲染出来却变成了在中间
这是因为子组件把除了两个具名插槽的内容以外的部分,都渲染进了匿名插槽中
也就是说,父组件的标签顺序不代表最后渲染出来的最终样式
2.3.在vue项目中使用具名插槽
- 父组件:FatherComponment.vue
<template>
<div>
<!-- 匿名插槽 -->
<!-- <son-componment>匿名</son-componment> -->
<!-- 具名插槽 -->
<son-componment>
<div>商品信息</div>
<template v-slot:toubu>头部</template>
<template v-slot:weibu>尾部</template>
<div><img src="https://ftp.bmp.ovh/imgs/2021/05/b86a125cadd68fb3.png" alt=""></div>
</son-componment>
</div>
</template>
<script>
import SonComponment from './SonComponment.vue';
export default {
components: {SonComponment},
};
</script>
<style scoped>
</style>
- 子组件SonComponment.vue
<template>
<div>
<header>
<slot name="toubu"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="weibu"></slot>
</footer>
</div>
</template>
<script>
export default {
};
</script>
<style scoped>
</style>
- 在router/index.js中引入父组件
略
2.4.具名插槽在网页中使用和在项目中使用的格式区别
在网页中
父组件是通过在子组件占位符中的带有slot的div标签<div slot="toubu">头部</div>
来准备插入内容的
<juming>
<div slot="toubu">头部</div>
<div slot="weibu">尾部</div>
</juming>
子组件是通过在需要的位置预留槽位<slot name="toubu"></slot>
来实现放置插入内容的
Vue.component("juming",{
template:`<div>
<header>
<slot name="toubu"></slot>
</header>
</div>`
...
});
在项目中
父组件是通过在子组件占位符中使用带有v-slot的template标签, <template v-slot:toubu>头部</template>
来准备插入内容的:
<son-componment>
<template v-slot:toubu>头部</template>
<template v-slot:weibu>尾部</template>
</son-componment>
子组件是通过在需要的位置预留槽位<slot name="toubu"></slot>
来实现放置插入内容的(跟在网页中的格式一样)
<template>
<header>
<slot name="toubu"></slot>
</header>
...
</template>
3.作用域插槽
3.1.作用域插槽的定义和用法
- 定义
本质是一个携带信息的匿名插槽 - 形式
作用域插槽可以携带数据:子组件提供数据,父组件提供样式 - 插槽可以访问相同的实例属性,即相同的"作用域",
访问子组件作用域时,把需要传递的内容绑到 slot 上,在父组件中用v-slot设置一个值来定义我们提供插槽的名字 - 插槽 prop
绑定在元素上的特性。
在父组件中,用 v-slot 设置一个值来定义我们提供的插槽 prop 的名字,然后直接使用
3.2.在网页中使用作用域插槽(匿名)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--默认存在一个根组件,是所有组件的父组件 -->
<div id="app">
<!-- 作用域插槽 -->
<zuoyongyu>
<span slot-scope="library">查询书籍:{{library.info}}</span>
</zuoyongyu>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//全局注册子组件zuoyongyu
Vue.component("zuoyongyu",{
data(){
return{
book:"javascript从入门到精通"
}
},
template:`<h1><slot :info="book"></slot>,剩余馆藏:2</h1>`
});
new Vue({
el:"#app"
});
/*
zuoyongyu:子组件
library:slot-scope接收的对象
info:library对象的属性
slot-scope:父组件通过 “slot-scope” 来接收子组件传过来的插槽数据,再根据插槽数据来填充插槽的内容
*/
</script>
</html>
3.3.在vue项目中使用作用域插槽(匿名插槽)
Center.vue:v-slot写在Login上
<Login v-slot:default="slotProp">
<span>{{slotProp.usertext.firstname}}</span>
<span>{{slotProp.usertext.lastname}}</span>
</Login>
这里的default是指子组件中是一个匿名插槽,由此可见,可以把default换成具名插槽
Login.vue
<template>
<div>
<slot v-bind:usertext="myname"></slot>
</div>
</template>
<script>
export default {
data(){
return{
myname:{
firstname:"张",
lastname:"三"
}
}
}
}
</script>
3.4.在vue项目中使用作用域插槽(具名插槽)
Center.vue:v-slot写在template上
<Login>
<template v-slot:header="slotProp">
<span>{{slotProp.usertext.firstname}}</span>
</template>
<template v-slot:footer="slotProp">
<span>{{slotProp.usertext.lastname}}</span>
</template>
</Login>
Login.vue:v-bind省略
<header> <slot name="header" :usertext="myname"></slot></header>
<footer> <slot name="footer" :usertext="myname"></slot></footer>