vuejs里的作用域插槽scopedSlots究竟有何用
前言作用域插槽可以使vue组件更具备通用性(versatile)和可复用性(reusable)。可能唯一不足的地方是其概念有些难懂,通常我遇到不好理解的代码,便会试图将它用到实际项目中,解决之前遇到的问题。下面的正文,便是讲述我在实际项目中遇到的问题,使用scopedSlots是如何解决它。点击链接你可以看到完整的代码正文在app.js里,构建my-list组件,渲染shapes和colors两个
前言
作用域插槽可以使vue组件更具备通用性(versatile)和可复用性(reusable)。可能唯一不足的地方是其概念有些难懂,通常我遇到不好理解的代码,便会试图将它用到实际项目中,解决之前遇到的问题。下面的正文,便是讲述我在实际项目中遇到的问题,使用scopedSlots是如何解决它。
点击链接你可以看到完整的代码
正文
在app.js
里,构建my-list
组件,渲染shapes
和colors
两个测试数组,接受传递的title
属性,其代码如下:
Vue.component('my-list', {
template: '#my-list',
props: [ 'title' ]
data() {
return {
shapes: [
{ name: 'Square', sides: 4 },
{ name: 'Hexagon', sides: 6 },
{ name: 'Triangle', sides: 3 }
],
colors: [
{ name: 'Yellow', hex: '#F4D03F', },
{ name: 'Green', hex: '#229954' },
{ name: 'Purple', hex: '#9B59B6' }
]
};
}
});
new Vue({
el: '#app'
});
在index.html
里,实现shapes
和colors
的数据渲染,以及编写my-list
组件里的template
<div id="app">
<my-list :title="Shapes">
<div class="list-item" v-for="item in shapes">
<div>{{ shape.name }} <small>({{ shape.sides }} sides)</small></div>
</div>
</my-list>
<my-list :title="Colors">
<div class="list-item" v-for="color in colors">
<div>
<div class="swatch" :style="{ background: color.hex }"></div>
{{ color.name }}
</div>
</div>
</my-list>
</div>
<script type="text/x-template" id="my-list">
<div class="my-list">
<div class="title">{{ title }}</div>
<div class="list">
<slot></slot>
</div>
</div>
</script>
添加一些css,可看到渲染效果如下图所示
虽然实现了两组列表,但是在组件实现内部,有重复性代码<div class="list-item" v-for="item in ...">
,如果我们能将其移入到my-list
组件内部,而不是放到父组件上实现,那该多好!scopedSlots成功解决了该问题。
scopedSlots
它之所以被叫作"scoped" slot,那是因为虽然它的template
放在父组件内渲染,但是父组件可以读取到子组件内指定的data数据
通过scopedSlots,我们改写app.js
里的代码
Vue.component('my-list', {
template: '#my-list',
props: [ 'title', 'items' ]
});
index.html
里,改动后的完整代码如下所示
<div id="app">
<my-list title="Shapes" :items="shapes">
<template scope="shape"> // 通过scoped,可访问到子组件内部单个数据shape
<div>{{ shape.name }} <small>({{ shape.sides }} sides)</small></div>
</template>
</my-list>
<my-list title="Colors" :items="colors">
<template scope="color">
<div>
<div class="swatch" :style="{ background: color.hex }"></div>
{{ color.name }}
</div>
</template>
</my-list>
</div>
<script type="text/x-template" id="my-list">
<div class="my-list">
<div class="title">{{ title }}</div>
<div class="list">
<div v-for="item in items">
<slot v-bind="item"></slot>
</div>
</div>
</div>
</script>
让我们先看shapes list
,该模板必须包含scope
属性,我们对该属性赋上一个别名shape
,该别名让我们能访问作用域属性。在模板内部,我们可以像之前代码那样显示shape list。
结束语
虽然在使用scopedSlots后,仍然和以前一样有那么多的HTML标记(markup),但是它已经将公共的功能委托到组件内部,这有利于系统代码的健壮性。
有兴趣的同学,可以看看原文链接
更多推荐
所有评论(0)