插槽
作用
Slot是为了更好的实现组件的组合而出现,特别是父子组件的内容
slot用法
①一般而言,组件标签间的内容会被抛弃
正常情况下,我们在自定义组件标签中定义的任何内容,都会被抛弃。都只会渲染出组件模板内容,如下:
②Slot可以把内容渲染进子组件
我们使用slot就能实现让我们的内容渲染进行子组件中,达到如同使用网页标签一样使用我们的组件标签
③组件标签中放入其他组件也能渲染进去
④slot中可以给默认值
⑤Slot给我们带来的好处
- 让我们如同使用网页标签一样使用组件标签
- 当我们要让组件组合使用,比如混合父组件的内容与子组件的模板时,特别有用
⑥具名slot (具有名字的插槽)——重点
完整代码
<!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">
<script src="./node_modules/_vue@2.6.10@vue/dist/vue.js"></script>
<title>slot插槽</title>
</head>
<body>
<div id="app">
<body-component></body-component>
<body-component>
<footer-component slot="footer"></footer-component>
<header-component slot="header"></header-component>
<main-component></main-component>
</body-component>
</div>
<script>
Vue.component('body-component', {
template: `
<div>
我是父组件
<slot name='header'></slot> <!-- 这里放入头部 -->
<slot></slot> <!-- 这里放入内容 -->
<slot name='footer'></slot> <!-- 这里放入尾部 -->
</div>`,
});
Vue.component('header-component', {
template: `
<div>我是头部</div>`,
});
Vue.component('main-component', {
template: `
<div>我是内容</div>`,
});
Vue.component('footer-component', {
template: `
<div>我是尾部</div>`,
});
var vueApp = new Vue({
el: '#app',
})
</script>
</body>
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190414175117402.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTM1MDIyNQ==,size_16,color_FFFFFF,t_70)
</html>
从上可知:
- 然后具名slot可以和没有名字的默认slot 共存,父组件中没有绑定具名slot的元素都将出现在子组件的默认slot中。【如果有多个无名的slot,那就会渲染插入多次】
- 如果父组件中含有没有绑定具名slot的元素,但是子组件中却无匿名默认slot时,父组件的那些原生将会被抛弃
⑦作用域插槽
作用域插槽的用法特点
- 在子组件中写slot插槽时,给上属性(这些属性能够被父组件拿到)
- 在父组件中渲染内容时一般写template标签,并且标签上有个scope属性,这个属性的值为一个对象,就是子组件的slot插槽上所有属性的集合
- 在父组件中就可以通过scope属性值这个对象操作子组件提供的数据
作用域插槽也是可以具名的,即为一个拥有名字的slot
之后上源码
<!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">
<script src="./node_modules/_vue@2.6.10@vue/dist/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<todo-list>
<template scope="slotVal" slot="li">
<span v-if='slotVal.val%2==0'>能被2整除</span>
<span v-else>不能</span>
{{slotVal.val}}
</template>
</todo-list>
</div>
<script>
Vue.component('todo-list',{
template:`
<ul>
<li v-for='v in list'>
<slot name='li' :val='v'>{{v}}</slot>
</li>
</ul>
`,
data:function() {
return {
list:[1,2,3,4,5]
}
},
})
var vueApp = new Vue({
el:'#app'
})
</script>
</body>
</html>
⑧访问slot插槽
效果图
注意: 空文本元素也会作为获取的slot数组中的一个元素
源码
<!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">
<script src="./node_modules/_vue@2.6.10@vue/dist/vue.js"></script>
<title>slot插槽</title>
</head>
<body>
<div id="app">
<body-component>
<footer-component slot="footer"></footer-component>
<header-component slot="header"></header-component>
<main-component></main-component>
</body-component>
</div>
<script>
Vue.component('body-component', {
template: `
<div>
<button @click='gelAllSlot'>获取所有的插槽</button>
<slot name='header'></slot> <!-- 这里放入头部 -->
<slot></slot> <!-- 这里放入内容 -->
<slot name='footer'></slot> <!-- 这里放入尾部 -->
</div>`,
methods: {
gelAllSlot:function(){
var header = this.$slots.header;
var main = this.$slots.default;
var footer = this.$slots.footer;
console.log(header,main,footer);//每个插槽打印出来都是一个数组
console.log(header[0].elm)
}
},
});
Vue.component('header-component', {
template: `
<div>我是头部</div>`,
});
Vue.component('main-component', {
template: `
<div>我是内容</div>`,
});
Vue.component('footer-component', {
template: `
<div>我是尾部</div>`,
});
var vueApp = new Vue({
el: '#app',
})
</script>
</body>
</html>