摘要:网络上大多数文章,也是千篇一律的翻译这句话,可是仅凭这一句话,我想象不到的使用场景。因为真正的使用场景下,子组件的数据都是来自父组件的。组件的数据都是来自调用者的,然后会把每一行的,在开发者需要时,传递出去。
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渲染列表,并且通过
4.父组件通过slot-scope="slotProps"的方式,接受todo对象,之后就可以通过slotProps.todo.xxx的方式来使用了
所以数据的流动经历了
父组件传递todos数组给子组件
子组件遍历todos数组,把里面的todo对象传递给父组件
好啦,这就是slot-scope的使用方法,就这么简单,完结撒花~
我贴出全部代码,方便大家自己研究
父组件的源码,也就是调用者
✓ {{slotProps.todo.text}}
子组件源码,也就是封装组件的人
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-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
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/96598.html
摘要:具名插槽可以在一个组件中出现次。出现在不同的位置。这个稍微难理解一点。使用非常方便,是基于搭建工程。地址点这里最后如果本文对你理解和有帮助,请不要吝啬手中的点赞哟。 作者/云荒杯倾 写在前面 vue中关于插槽的文档说明很短,语言又写的很凝练,再加上其和methods,data,computed等常用选项使用频率、使用先后上的差别,这就有可能造成初次接触插槽的开发者容易产生算了吧,回头再...
摘要:它取代了和这两个目前已被废弃但未被移除且仍在文档中的特性。例外情况当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。如下,让后备内容默认内容替换正常情况下的绑定在元素上的特性被称为插槽。 最近忙着写一些组件,关于插槽这一块自己还是用着 slot 和 slot-scope,然后看了一下文档的更新,于是又重新把插槽学习了一篇,下面一段是文档中的说明: 在 2.6.0 中...
摘要:它取代了和这两个目前已被废弃但未被移除且仍在文档中的特性。例外情况当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。如下,让后备内容默认内容替换正常情况下的绑定在元素上的特性被称为插槽。 最近忙着写一些组件,关于插槽这一块自己还是用着 slot 和 slot-scope,然后看了一下文档的更新,于是又重新把插槽学习了一篇,下面一段是文档中的说明: 在 2.6.0 中...
摘要:另外需要说明的是,这里只是冻结了的值,引用不会被冻结,当我们需要数据的时候,我们可以重新给赋值。1 状态共享 随着组件的细化,就会遇到多组件状态共享的情况,Vuex当然可以解决这类问题,不过就像Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是vue.js 2.6新增加的Observable API ,通过使用这个api我们可以应对一些简单的跨组件数...
阅读 1619·2019-08-30 15:44
阅读 2531·2019-08-30 11:19
阅读 362·2019-08-30 11:06
阅读 1529·2019-08-29 15:27
阅读 3054·2019-08-29 13:44
阅读 1599·2019-08-28 18:28
阅读 2318·2019-08-28 18:17
阅读 1941·2019-08-26 10:41