这节课我们来学习的还是插槽的知识点,主要学习内容是动态插槽名和作用域插槽。
我们接着上节课的代码来编写哈。
<script>
const app = Vue.createApp({
data() {
return {
message: "hello world!"
}
},
template: `<div>
<Shop>
<template #shopName>福乐家购物商店</template>
<span>我是店员小红</span>
<template #goodsList>
<div>
<p>本店销售以下商品</p>
<ol>
<li>咖啡</li>
<li>可乐</li>
<li>泡面</li>
</ol>
</div>
</template>
</Shop>
</div>`
})
app.component("Shop",{
template:`
<div>
<h2>
<slot name="shopName" />
</h2>
<div>
<slot />
</div>
<div>
<slot name="goodsList"/>
</div>
</div>
`
})
const vm = app.mount("#app")
</script>
动态插槽名
上节课我们学习到了具名插槽,就是给插槽取个名字,让插槽内容能够对号入座,在设置插槽内容时我们通过在 v-slot:插槽名
来传递内容给指定插槽,这里的插名其实是可以设置成动态的,可以用一个变量来设置插槽名,也可以通过修改变量值来实现动态切换插槽名。
const app = Vue.createApp({
data() {
return {
slotName1:"shopName",
slotName2: "goodsList"
}
},
template: `<div>
<Shop>
<template v-slot:[slotName1]>福乐家购物商店</template>
<span>我是店员小红</span>
<template #[slotName2]>
<div>
<p>本店销售以下商品</p>
<ol>
<li>咖啡</li>
<li>可乐</li>
<li>泡面</li>
</ol>
</div>
</template>
</Shop>
</div>`
})
像我们这里这样的写法,使用了两个变量slotName1 slotName2的值来设置插槽名。
作用域插槽
在某些场景下插槽的内容可能想要同时使用父组件和子组件的数据。要做到这一点,我们需要一种方法来让子组件在渲染时将一部分数据提供给插槽。
我们来举个例子,我们先删除掉多余的代码,再来写一个商品列表组件,代码如下:
<script>
const app = Vue.createApp({
data() {
return {
message: "hello world!"
}
},
template: `
<div>
<goods-list/>
</div>
`
})
app.component("goodsList",{
data(){
return {
list:["咖啡","可乐","泡面"]
}
},
template:`
<div>
<p>本店销售以下商品</p>
<div v-for="(item,index) of list" :key="index" >{{item}}</div>
</div>
`
})
const vm = app.mount("#app")
</script>
目前我们用 v-for 来遍历了一个div得到了一个列表,但是在某些情况下,我们可能需要自定义列表项,比如我们想修改列表项里面的排版或者样式,但是我们goodsList组件里面又给我们固定写死了,没办法修改。如果想要实现这样需求,我们就可以用到插槽了。
我们直接用v-for来遍历一个插槽。
<slot v-for="(item,index) of list" :key="index" >{{item}}</slot>
然后就可以到父组件里面来自定列表项模版了
<goods-list>
<div>xxx</div>
</goods-list>
现在到浏览器看 应该是可以看到三行xxx,我们只需要把xxx替换列表数据是不是就行了呢,那列表数据它是goodsList组件内部,我们需要怎么拿呢?其实也简单,我们可以在goodsList组件内部<slot>
上把数据传出去,直接通过自定义属性的方式把值传出去。
<slot v-for="(item,index) of list" :key="index" :item="item" ></slot>
然后父组件里面通过v-slot声明一个自定变量就可以把数据取出来,取出来之后把值插入到模版里就行了。
<goods-list v-slot="props">
<div style="color:pink">{{props.item}}</div>
</goods-list>
这样我们就可以实现一个可自定义列表项的商品列表,顺便我还把字体颜色给改成了猛男粉。
具名作用域插槽
上面我们演示案例中,都是通过默认插槽来实现的,具名插槽略微有点不一样。
先给插槽取个名listItem
传值的方式是一样的。
<slot name="listItem" v-for="(item,index) of list" :key="index" :item="item" ></slot>
取值的方式有点不一样,我们需要使用v-slot
先来指定插槽名称后面来自定义变量props变量接口数据。
<goods-list >
<template v-slot:listItem="props">
<div style="color:pink">{{props.item}}</div>
</template>
</goods-list>
优化商品列表
插槽的内容我们算是学习完了,我可以根据学过知识点来优化一下这个商品列表组件。
我们学过插槽默认内容,这样我们就要给列表设置一个默认列表项模版,当我们没有自定义列表项需求的时候让它显示默认的模版。
<slot name="listItem" v-for="(item,index) of list" :key="index" :item="item" >
<div>{{item}}</div>
</slot>
当我们需要自定义列表项的时候,我们只需要在给它传入一个name为listItem的插槽模版就可以了
<goods-list >
<div style="color:pink">{{props.item}}</div>
</goods-list>