什么是slot插槽
(1)slot插槽的目的:让我们原来的设备具备更多的扩展性
(2)组件的插槽:组件的插槽也是为了让我们的封装更具有扩展性,让使用者可以决定组件内部的一些内容到底展示的是什么
例如: 某宝各个页面的导航栏它既有相同的部分又有不相同的部分,那么这个组件就不能是固定下来的,其不同的部分就要用到插槽(抽取共性、保留不同)
插槽的使用
1、插槽基本使用:在组件模板中使用 slot
2、插槽的默认值:如果没有在该组件中插入任何其它元素则显示默认值,有其它元素则替换默认值
3、如果有多个值,同时放入组件进行替换时,一起作为替换元素
注释部分为特别关注
<body>
// <!-- 父组件模板 -->
<div id="app">
// <!-- 插槽基本使用,显示默认值 -->
<cpn></cpn>
<!-- 替换默认值 -->
<cpn><button>点我</button></cpn>
// <!-- 多个值替换默认值 -->
<cpn>
<h2>1</h2>
<h2>2</h2>
<h2>3</h2>
</cpn>
</div>
//<!-- 子组件模板 -->
<template id="cpn">
<div>
<h2>----------</h2>
<slot><h2>我是默认值</h2></slot>
</div>
</template>
<script src="../vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"我是Vue实例"
},
components:{
cpn:{
template:"#cpn",
}
}
})
</script>
</body>
具名插槽
当有多个插槽时,使用具名插槽。不同的插槽要有不同的 name
步骤:
(1)在组件模板中对多个 slot 插槽 取不同的name
(2)在父模板中替换某一插槽的默认值时使用slot属性
注释部分为特别关注
<body>
// <!-- 父组件模板 -->
<div id="app">
//显示默认值
<cpn></cpn>
// <!-- 替换标签要用slot属性 -->
<cpn><h5 slot="center">我替换了左边</h5></cpn>
</div>
//<!-- 子组件模板 -->
<template id="cpn">
<div>
<h2>-------</h2>
//<!-- 不同的插槽有不同的name -->
<slot name="left"><span>左</span></slot>
<slot name="center"><span>中</span></slot>
<slot name="right"><span>右</span></slot>
</div>
</template>
<script src="../vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"我是Vue实例"
},
components:{
cpn:{
template:"#cpn",
}
}
})
</script>
作用域插槽
什么是编译作用域
注意:
(1) 父组件模板中所使用的变量都会到Vue实例中查找
(2)子组件模板中所使用的变量都会到组件中查找
注释部分为特别关注
<body>
//<!-- 父组件模板 -->
//<!-- 所使用的变量都会到Vue实例中查找 -->
<div id="app">
<cpn v-show="isshow"></cpn>
</div>
//<!-- 子组件模板 -->
<template id="cpn">
<div>
<h2>我是子组件</h2>
//<!-- 所使用的变量都会到组件中查找 -->
<h2 v-show="isshow">我不会显示</h2>
</div>
</template>
<script src="../vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"我是Vue实例",
//父组件中变量
isshow:true
},
components:{
cpn:{
template:"#cpn",
},
//子组件中变量
data(){
return {
isshow:false
}
}
}
})
</script>
</body>
作用域插槽使用方法
作用域插槽:使用slot-scope
注意:
(1)在子组件模板中要绑定data
(2)在父组件模板中首先要使用template作为根标签,在template中添加slot-scope="slot"
(3)在template中就可以使用slot.data来对子组件的数据作相应的改变
注释部分为特别关注
<body>
//<!-- 父组件模板 -->
<div id="app">
<cpn></cpn>
<cpn>
//<!-- 获取子组件中的books数据 -->
<template slot-scope="slot">
<span v-for="book in slot.data">{{book}}--</span>
</template>
</cpn>
<cpn>
//<!-- 获取子组件中的books数据 -->
<template slot-scope="slot">
//去掉最后的“--”
<span>{{slot.data.join("-")}}</span>
</template>
</cpn>
</div>
//<!-- 子组件模板 -->
<template id="cpn">
<div>
<slot :data="books">
<ul>
<li v-for="book in books">{{book}}</li>
</ul>
</slot>
</div>
</template>
<script src="../vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"我是Vue实例",
},
components:{
cpn:{
template:"#cpn",
data() {
return {
books:["红楼梦","西游记","三国演义","水浒传"]
}
}
}
}
})
</script>
</body>
插槽最新使用方法
在vue v2.6.0中,新引入了v-slot指令,他取代了slot和slot-scope这两个目前已经被废弃但是为被移除的特性。
我在这里将使用v-slot指令对上述例子做更改,但效果相同
具名插槽v-slot写法
(1)在下面代码中,我只展现了更改的部分,其余代码与上面具名插槽是一样的
(2)使用方法:使用v-slot : name ,并且要特别注意v-slot 只能添加到 <template> 或自定义组件上,这点与弃用的 slot 属性不同
(3)如果想调用默认插槽,可以使用使用v-slot : default
//<!-- 父组件模板 -->
<div id="app">
//<!-- 显示默认值 -->
<cpn>
<template v-slot:default>
<h2>不会显示我</h2>
</template>
</cpn>
// <!-- 替换标签要用 v-slot: name-->
<cpn>
<template v-slot:center>
<h5>我替换了左边</h5></cpn>
</template>
</div>
作用域插槽最新写法
(1)在下面代码中,我只展现了更改的部分,其余代码与上面作用域插槽是一样的
(2)使用方法:v-slot :name=后边是组件内部绑定作用域值的映射slot props(name可以为default【默认】也可以是插槽的名字【具名名插槽】)。绑定到 子组件<slot> 元素上的属性我们称之为 slot props ,在父组件模板中使用slotprops.数据名.变量名
(3)在下面例子中我选择 slotProps 作为 slot props 的名字,这个名字可以自定义的。
//<!-- 父组件模板 -->
<div id="app">
<cpn></cpn>
<cpn>
// <!-- 获取子组件中的books数据 -->
//更改部分
<template v-slot="slotProps">
<span v-for="book in slotProps.data.books">{{book}}--</span>
</template>
</cpn>
<cpn>
//<!-- 获取子组件中的books数据 -->
//更改部分
<template v-slot="slotProps">
//<!-- 去掉最后的“--” -->
<span>{{slotProps.data.join("-")}}</span>
</template>
</cpn>
</div>
v-slot总结和注意事项
(1)组件中可以使用template标签,加v-slot:name指令可以指定具名插槽,当没有指定插槽name时,默认出口会带有隐含的名字“default”,为默认。
(2)根组件可以利用v-slot:name="slotProps"接收子组件中的数据,子组件中插槽只要命名并绑定数据就可以了
(3)如果被提供的内容只有一个默认插槽时,组件的标签可以直接被当做插槽的模板来使用
(4)v-slot的缩写是#,若想使用简写语法,则务必指定插值的名字或者default