在Vue中,插槽slot是可以由组件使用者来自定义内容,用来做组件的扩展。
如下,我们封装了一个列表组件
<template>
ul
li(v-for="item in list")
span(v-html="item.text")
</template>
<script>
export default{
props:["list"]
}
</script>
默认该组件可以让使用者传入list,遍历显示list中每个item的text值
但是,当使用者,不仅仅用来显示text值时,组件就要求做调整
如果不同使用者想要呈现的方式各异,我们没理由为这不同的呈现做特殊定制
这时候插槽就派上用场,将组件改造如下
<template>
ul
li(v-for="item in list")
slot(:item="item")
span(v-html="item.text")
</template>
<script>
export default{
props:["list"]
}
</script>
使用者就可以自定义插槽内容,如list就是我们封装好的组件
可以显示内容项的名字
<list><tempalte scope="props"><span v-html="props.item.name"></span></template></list>
可以显示内容项的图片和描述
<list>
<tempalte scope="props">
<div>
<img :src="props.item.img"/>
<span v-html="item.desc"></span>
</div>
</template>
</list>
要注意的是,插槽也会带来一定的问题:Vue内部检测刷新的机制中,如果组件A中包含了插槽元素,子节点之类的,父组件更新的时候,该组件A会被强制更新。
如果组件A中render渲染比较耗时的话,要做多一层封装;
如下(其中test是我们上面封装好的组件)
<div id="app">
<input type="text" v-model="name"/>
<test :list="list" @hook:updated="testUpdated"><template scope="props"><span v-html="props.item.name"></span></template></test>
</div>
<script>
new Vue({
el:"#app",
data:{
list:[{name:"123"},{name:"456"},{name:"789"}],
name:"test"
},
methods:{
testUpdated:function(){
console.log("d")
}
}
})
</script>
在这里,每次修改input框值,都会触发组件test的更新
网友评论