Fork me on GitHub

有趣的slot-scope

今天看到一篇文章讲了slot插槽, 其中一个有意思的特殊属性,插槽作用域,应用于无渲染,纯逻辑的组件的例子。
Vue中的无渲染组件
正好记录一下,将来能应用带开发当中。

slot插槽

1
2
3
4
5
6
7
8
9
<tags v-model="tags">
<div slot="test" slot-scope="{removeTag, inputAttrs, addTag, inputEvents}">
<span class="tags-input-tag" v-for="tag in testTags">
<span>{{ tag }}</span>
<button type="button" class="tags-input-remove" @click="removeTag(tag)">×</button>
</span>
<input v-on="inputEvents" v-bind="inputAttrs" />
</div>
</tags>

slot-scope可以实现将子组件中的属性通过插槽传递给父组件。slot-scope 的值将被用作一个临时变量名,此变量接收从子组件传递过来的 prop 对象。
这样可以很方便的让表现与逻辑分离,ui渲染专心做渲染的东西,数据的逻辑交给子组件处理。就可以实现表现多元化,业务可重用的功能。

解释一下,上面的v-on="inputEvents"表示默认绑定了slot-scope传来的属性inputEvents下面的对象,对象里面包含input和keydown事件,
即等同于分开写@input="inputEvents.input"@keydown="inputEvents.keydown"

v-bind="inputAttrs"也是表示默认绑定了属性inputAttrs下面的对象,对象里面包含value属性,即等同于写成:value=inputAttrs.value

无渲染,纯逻辑组件

1
2
3
4
5
<template>
<slot :tags="value" :inputAttrs="{value: newTag}" :inputEvents="{input, keydown}"
:addTag="addTag"
:removeTag="removeTag"></slot>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
export default {
props: ['value'], // v-model默认绑定的prop为value
data() {
return {
newTag: ''
}
},
methods: {
keydown(e) {
if (e.keyCode === 13) {
e.preventDefault()
this.addTag()
}
},
input(e) {
this.newTag = e.target.value;
},
removeTag(tag) {
this.value.filter(t => t !== tag)
},
addTag() {
this.value.push(this.newTag);
this.$nextTick(() => {
this.newTag = '';
});
}
}
}

如此一来,子组件和父组件之间的通信就不需要充斥着各种各样的emit了。

-------------本文结束感谢您的阅读-------------
如果您觉得受益了,欢迎打赏鼓励。