Vue的slot-scope的场景的个人明白
这篇文章不是纯真把文档的话和api拿来翻译和演示,而是谈谈我关于slot-scope的运用场景的个人明白,假如明白毛病,迎接议论!
Vue的插槽slot,分为3种
- 匿名插槽
- 签字插槽
- 作用域插槽
前两种很好明白,不管就是子组件里定义一个slot占位符,父组件挪用时,在slot对应的位置添补模板就好了。
作用域插槽的慨念,文档却只有一句简朴的形貌
有的时刻你愿望供应的组件带有一个可从子组件猎取数据的可复用的插槽。
收集上大多数文章,也是一模一样的翻译这句话,然则仅凭这一句话,我设想不到slot-scope的运用场景。
媒介
引见了写这篇文章的因由,接下来简述一下本文的头绪
- 起首,我会连系文档上todo-list的例子,来简朴申明一下slot-scope的运用体式格局
- 其次,会运用但不明白什么时刻用,就没有什么意义,所以本文第二部份,谈一下个人关于其运用场景的明白
- 末了,是我翻阅收集上关于slot-scope时,看到的一些我以为不太适当的案例
官方文档slot-scope的示例
下面是2个父子的vue组件,先解释一下2个组件做了什么事变
- 父组件仅仅是挪用了子组件
- 子组件内部完成了一个todolist列表
我发起从数据活动的角度,明白插槽作用域的运用体式格局,(先学会怎样用,临时不必明白为何要这么用,运用场景是第二部份)
- 1.父组件通报了todos数组给子组件
- 2.子组件经由历程props接收了数组数据,这里应当没有任何题目
- 3.子组件拿到数组后v-for衬着列表,而且经由历程 <slot :todo=”todo”>的体式格局,把数组内的每个todo对象,通报给父组件
- 4.父组件经由历程slot-scope=”slotProps”的体式格局,接收todo对象,以后就能够经由历程slotProps.todo.xxx的体式格局来运用了
所以数据的活动阅历了
- 父组件通报todos数组给子组件
- 子组件遍历todos数组,把内里的todo对象通报给父组件
好啦,这就是slot-scope的运用要领,就这么简朴,结束撒花~
我贴出悉数代码,轻易人人本身研讨
父组件的源码,也就是挪用者
<template>
<todo-list :todos="todos">
<template slot-scope="slotProps">
<span v-if="slotProps.todo.isComplete">✓</span>
<span>{{slotProps.todo.text}}</span>
</template>
</todo-list>
</template>
<script>
import todoList from './todoList'
export default {
data () {
return {
todos: [
{
id: 0,
text: 'ziwei0',
isComplete: false
},
{
text: 'ziwei1',
id: 1,
isComplete: true
},
{
text: 'ziwei2',
id: 2,
isComplete: false
},
{
text: 'ziwei3',
id: 3,
isComplete: false
}
]
}
},
components: {
todoList
},
}
</script>
子组件源码,也就是封装组件的人
<template>
<ul>
<li v-for="todo in todos" :key="todo.id">
<slot :todo="todo">
</slot>
</li>
</ul>
</template>
<script>
export default {
props: {
todos: {
type: Array
}
}
}
</script>
slot-scope的运用场景的个人明白
设想一个场景:
当你要给同事封装一个列表组件,你就须要运用作用域插槽(注重是列表或许相似列表的组件)
你开辟的这个列表组件要怎样运用呢?
平常来说作为列表组件的挪用者,你的同事前做ajax要求,拿到一个如许的数组
todos: [
{
id: 0,
text: 'ziwei0',
isComplete: false
},
{
text: 'ziwei1',
id: 1,
isComplete: true
},
{
text: 'ziwei2',
id: 2,
isComplete: false
},
{
text: 'ziwei3',
id: 3,
isComplete: false
}
]
以后会把todso通报给列表组件吧,那末列表组件内部做什么事变呢?
列表内部一定会v-for去帮你的同事衬着这个数组嘛。 就相似element-ui里的table组件一样
题目的症结就在这里
列表组件的轮回,是发生在组件内部的,所以经由历程 v-for=”todo in todos” ,列表组件很轻易拿到每一项todo,但列表拿到数据没用呀,列表只是一个瓜皮,它又不懂营业逻辑
这个数据是你同事的营业数据,所以这个数据必须得交给组件的挪用者,也就是把数据交给你的同事才对。
那末你怎样才能把每一项的todo数据给通报出去呢?
你会发明没有办法!
不管是用$emit、vuex照样localStorage,能够考虑一下,会发明没有适宜的机遇,能让你把todo通报出去
所以为了应对这个场景下,发清楚明了作用域插槽,列表组件能够经由历程<slot :todo=”todo”></slot>通报todo出去
你的同事能够经由历程 slot-scope=”slotsProps”拿到todo。
回复几个疑问,实在假如你看懂上面的题目,应当能够回复下面的题目。这也是我曾的疑问
疑问1:平常不是我们传参数来挪用组件吗?为何组件还把数据通报返来?
确实,挪用ui组件时平常是我们通报设置参数给他们。
然则就像elemnt-ui的table组件,你把数组通报给table后,是否是有时刻须要拿到某一行的row对象
并依据row对象里的字段,来推断一些内容的显现隐蔽?
由于轮回的历程发生在table组件内部,所以table组件能够轻易的猎取到每一项数据,然则这些数据终究不是给组件的,而是我们本身要用的营业数据。所以也须要一个体式格局,让挪用者能拿到本身想要的数据
疑问2: 既然子组件终究还要把我给他的数据,再返还给我,那我当初还干吗给它,能不能就本身在父组件里玩?
假如你不把数据给子组件固然能够。然则就即是扬弃掉了子组件的封装,只能你直接在父组件本身写一个列表
毕竟你不把数据给子组件,子组件还衬着个锤子?没有父子关系的话,也就不必什么插槽了。
然则咱不是为了封装后,能够复用嘛,总不能永久不必组件嘛
疑问3: 父组件须要子组件的数据?那不会有$emit和vuex嘛,为何要有slot-scope?
$emit和vuex是数据通报的一种要领,然则你能够尝试用$emit和vuex把todo通报给父组件。
你会发明确实没有适宜的钩子、机遇来$emit数据
一些网上个人以为不太适当的例子
我以为几种说法是不太适当的,也是给我形成一些疑心的
- slot-scope是什么?就是把子组件的数据通报给父组件的一种体式格局
这类说法,会让我以为slot-scope跟emit和vuex是一类东西
- 在一些例子中,把数据定义在写死在列表组件中,展现怎样把数据通报出去
这些举例子的不适当的地方,我以为是不应当把数据定义在子组件里。
由于真正的运用场景下,子组件的数据都是来自父组件的。作为组件内部应当坚持纯洁。
就像element-ui里的table组件,一定不会定义一些数据在组件内部,然后通报给你。
table组件的数据都是来自挪用者的,然后table会把每一行的row,在开辟者须要时,通报出去。
这些例子虽然不是毛病,然则我以为反而不利于明白slot-scope