vue scope slots, you really understand?

Original Address: https://www.jianshu.com/p/e10baeff888d

Foreword

Internet search a lot of explanation about the scope of the slot, do not write very specific feeling of it, I think it should have a deep understanding of the components will touch on this issue, which also share my own for slot-scope a little understanding.

  • slot we look at the document know everything, and nothing more than dig a hole in the sub-assembly, put something inside the pit is determined by the parent component.
// sub-assembly 
<Template> 
  <slot> to ah, I've dug a hole </ slot> 
</ Template> // parent component 
<Template> 
  <Child> 
   <-! Customizations incoming sub-assemblies, will fill the slot slot subassembly -> 
    <span> I put in this span, willing, then, to put components are OK </ span> 
  </ child> 
</ Template>

 

  1. To slot the incoming plain text
 
slot incoming plain text
  1. To slot a pass Imaging Component
 
Incoming component slot
  • Named slot is also very simple, such as a plurality of slots, I as a parent components, sub-assemblies definitely want to distinguish several slots, then use name tags to identify the property slot, while the parent component to be decided What slot which put what, you must assign a value to the slot attribute name passed to the corresponding slot. If no name attribute slot, the slot is anonymous, while the parent component does not specify the content attribute slot, it will be thrown into anonymous slot.
// sub-assembly 
<Template> 
    <Section> 
        <slot name = "Article This article was-title"> here put title </ slot> 
        <slot> here put Author </ slot> 
        <slot name = "Content-Article This article was"> here put articles content </ slot> 
    </ Section> 
</ Template> // parent component 
<Template> 
    <Section> 
        <slot-Child> 
            <h1 slot = "Article This article was-title"> VUE scope slots, you really understand yet ? </ h1> 
            <the p-slot = "Content-Article This article was"> seems a bit understand </ the p-> 
            <div> Wang Wu </ div> 
        </ slot-Child> 
    </ Section> 
</ Template>

 

  • It is the most difficult to understand the scope of the slot. Read the documentation of friends may also be a little dizzy, probably within the scope of said slot, a parent can get the data component sub-assemblies. Subassembly can bind in the slot label property values, such as:
<slot :nickName="'Tusi'"></slot>

 

NickName get the value of the parent element objects by slot-scope binding.

<template>
    <section>
        <slot-child>
            <template slot-scope="scope">
                <div>{{scope.nickName}}</div>
            </template>
        </slot-child>
    </section>
</template>

 

Here we should have doubt. What's the use? I transfer data to sub-assemblies with $ emit parent component is not on the list?

A little understanding of the scope of slots

I think from the data flow between the components to think about scenarios scope slots.

Assume that the first scenario, you need to write a merchandise card assembly, and through the loop to display multiple cards, and can respond to the requirements of each picture on the card or other content click event and jump to the product details page, how would you write?

 
Taobao products list

I will use the following approach, first written as a commodity card assembly Commodity.vue, and in CommodityList.vue with a v-for display of goods handled card list.

<commodity v-for="(item,index) in commodities" @clickCommodity="onCommodityClick"></commodity>

 

Commodity组件通过$emit像父组件传递clickCommodity事件,并携带商品数据,父组件即可在onCommodityClick方法中得到数据,进行业务处理,这样便完成了一个基本的由子到父的数据传递。

如果再往上抽象一下呢?比如我有多个运营栏目,像淘宝首页有“有好货”,“爱逛街”这样两个栏目,每个栏目下都需要有一个商品卡片列表,那么商品卡片列表CommodityList.vue就要抽成组件了。而这个包含多个运营栏目的vue组件我假设它叫ColumnList.vue,在其中通过v-for调用了CommodityList组件。

 
淘宝运营栏目列表

注意:业务来了,我希望把点击商品卡片的业务放在ColumnList.vue中处理。你们想象一下要怎么做?一种土办法就是商品按钮点击时,Commodity组件$emit通知CommodityList.vue,而CommodityList接着把事件用$emit往上抛,那么ColumnList.vue就能处理这个点击事件了。这样做完全没有问题,但是显得子组件很不纯粹,跟业务都扯上关系了。

那么如何优雅地解决这个问题呢?这个时候,作用域插槽真正派上用场了。

通过作用域插槽将本应该由CommodityList处理的商品卡片点击业务onCommodityClick提升到ColumnList处理。

<el-row :gutter="20">
        <el-col :span="12" v-for="(column, index) in columnList" :key="index">
            <el-card class="box-card card-column">
                <div slot="header" class="clearfix">
                    <span>{{column.columnName}}</span>
                </div>
                <commodity-list :commodities="column.commodityList">
                    <template slot-scope="scope">
                    <!-- 这里只需要给Commodity组件传入数据,响应Commodity组件的clickCommodity事件即可。
                        事件不必携带参数,完全符合父到子的数据流向,而不会发生子组件又给父组件反向发数据的情况 -->
                        <commodity :modityData="scope.row" @clickCommodity="onCommodityClick(scope.row)"></commodity>
                    </template>
                </commodity-list>
            </el-card>
        </el-col>
</el-row>

 

而CommodityList组件内部应该是改造成这样,slot接收来自父组件的商品卡片组件,这里面不涉及关于商品组件的业务,只关注其他业务和布局即可。最终就实现了组件和业务的剥离,这也是组件化的精髓所在吧。不知道有没有帮到您呢?

<el-row :gutter="20">
        <el-col :span="8" v-for="(item, index) in commodities" :key="index" style="margin-top:20px;">
            <slot :row="item"></slot>
        </el-col>
</el-row>

 

这是我实现的效果,忽略样式吧,原理都懂了,做个漂亮的卡片有多难?

 

 
DIY栏目列表

 

 
DIY栏目列表点击商品卡片

总结一下,作用域插槽适合的场景是至少包含三级以上的组件层级,是一种优秀的组件化方案!

欢迎小伙伴们来踩我的主页

 
 
6人点赞
 
Vue

 

 

Guess you like

Origin www.cnblogs.com/imPedro/p/11986815.html