作用域插槽主要应用于父组件对子组件的内容进行加工处理。这样说太抽象,我用例子说明。
先看下面代码和实现的效果:
分析:
代码实现的效果是显示水果列表,并且orange加粗。代码本身使用组件将水果名称,样式效果固定在了子组件中,这样数据是写死的,并不推荐这么做。
实现的效果应当是通过动态控制的方式决定哪种水果是加粗的。
同时template中的列表应当是动态遍历生成的,不应是写死的。所以要提供数组,使用v-for生成列表;子组件的数据也一般由父组件传递,所以数据内容要在父组件中写出。
下面看更新的代码及其效果:
分析:
这里把原有的数据以对象的形式存储在data中,通过父组件属性绑定,子组件props接收,将数据传递给了子组件。进而使用遍历数据的方式渲染列表。
但是加粗的样式没有显示出来。也许你会想,在子组件中通过v-if控制显示不就解决了?其实子组件一旦封装好,后期很少再去变动。所以我们一般从父组件直接决定子组件哪个条目是加粗显示。这就是作用域插槽要解决的问题。
下面是作用域插槽的用法:
首先将原有的插值表达式换为slot,同时绑定一个属性info,这个属性名不是固定的,info绑定item。
父组件中加入template标签,同时带有属性slot-scope,slot-scope是固定名称,一般起名为slotProps。注意这个slot-scope属性,它能获取子组件中slot绑定的info。就好像slot-scope可以自动寻找到子组件的slot一样,通过slotProps.info就得到了info绑定的item。这样我们就可以在父组件中直接操控子组件的条目。
最终代码片:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<fruit-list :list='list'>
<template slot-scope='slotProps'>
<strong v-if='slotProps.info.id==2'>{{slotProps.info.name}}</strong>
<span v-else>{{slotProps.info.name}}</span>
</template>
</fruit-list>
</div>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
Vue.component('fruit-list', {
props: ['list'],
template: `
<div>
<li :key='item.id' v-for='item in list'>
<slot :info='item'></slot>
</li>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {
list: [{
id: 1,
name: 'apple'
},{
id: 2,
name: 'orange'
},{
id: 3,
name: 'banana'
}]
}
})
</script>
</body>
</html>