vue slot

作者: 神话降临 | 来源:发表于2018-12-28 14:33 被阅读0次

    前言

    slot插值官方网站的介绍是一笔带过,有很多想使用的看到这个情况,就会放弃,但是这个着实是一个非常好用的功能

    功能介绍

    • 匿名插槽
    //Child.vue
    <template>
        <div>
            <slot>我是子组件</slot>
        </div>
    </template>
    
    //Parent.vue
    <template>
        <div>
            <Child>
                被父组件引用
            </Child>
        </div>
    </template>
    

    效果图

    image.png
    • 具名插槽
    //Child.vue
    <template>
        <div>
            <slot name="first">我是子组件第一行</slot>
            <slot name="second">我是子组件第二行</slot>
            <slot name="third">我是子组件第三行</slot>
        </div>
    </template>
    
    //Parent.vue
    <template>
        <div>
            <Child>
                <div slot="first">被父组件修改的第一行</div>
                <div slot="second">被父组件修改的第二行</div>
            </Child>
        </div>
    </template>
    

    //效果图


    image.png

    这上面的两种用法 大部分人应该都用过了,其实就是子组件留一个插槽,如果父组件有定制化的内容直接修改就可以达成目的

    • 有值插槽(作用域插槽)
      就是子组件插槽上带的有值(这个值可以是子组件自己的,也可以是父组件传给子组件的),并把这些值暴露给父组件
      第一种用法
    //Child.vue
    <template>
        <div class="child-style">
            <slot :data="testData">我是子组件第一行</slot>
        </div>
    </template>
    testData: ['apple','banana','orange']
    
    //Parent.vue
    <template>
        <div>
            <Child>
                <template slot-scope="fruits">
                {{fruits.data}}
                </template>
            </Child>
        </div>
    </template>
    

    //效果图


    image.png

    第二种用法

    //Child.vue
    <template>
        <div class="child-style">
            <slot :data="testData">我是子组件第一行</slot>
        </div>
    </template>
    
    //Parent.vue
    <template>
        <div>
            <Child>
                <template slot-scope="fruits">
                    <div v-for="item in fruits.data" :key="item">{{item}}</div>
                </template>
            </Child>
        </div>
    </template>
    

    //效果图


    image.png

    第三种用法

    //Child.vue
    <template>
        <div class="child-style">
            <slot name="first" :data="fruiltData">我是子组件第一行</slot>
            <slot name="second" :data="animalData">我是子组件第二行</slot>
        </div>
    </template>
    
    //Parent.vue
    <template>
        <div>
            <Child>
                <template slot="first" scope="firstData">
                    <div v-for="item in firstData.data" :key="item"> {{item}}</div>
                </template>
                <template slot="second" scope="secondData">
                    <div v-for="list in secondData.data" :key="list"> {{list}}</div>
                </template>
            </Child>
        </div>
    </template>
    

    //效果图


    image.png

    使用场景举例

    • 第一个场景
      子组件定义大部分功能,父组件自身完成定制(仅属于自己)的功能

    流程
    父组件动态请求值给子组件
    子组件绑定数据然后把接口和数据在暴露给父组件

    //Child.vue
    <template>
        <div class="child-style">
            <slot name="first" :data="testData">我是子组件第一行</slot>
        </div>
    </template>
    
    <script>
        export default {
            name: 'Child',
            props: {
                testData: Array
            },
            data(){
                return{
    
                }
            }
        }
    </script>
    
    <style lang="scss" scoped>
        .child-style{
            div{
                background: #00c585;
                color: #fff;
                line-height: 30px;
            }
        }
    </style>
    
    
    //Parent.vue
    <template>
        <div>
            <Child :testData="row">
                <template slot="first" scope="arrayList">
                    <div v-for="item in arrayList.data" :key="item">{{item }}</div>
                </template>
            </Child>
        </div>
    </template>
    
    <script>
        import Child from './Child';
        export default {
            name: 'parent',
            data(){
                return{
                    row:["apple",'banana','orange']
                }
    },
            components:{
                Child
            }
        }
    </script>
    

    //效果图


    image.png

    可能有些人不太理解为什么 我不直接在子组件里动态请求数据,然后处理好所有的逻辑,父组件直接调用,其实这种一种很理想的做法,但是大多数开发的时候是不会这么理想的
    举个例子来说,我有一个子组件Child.vue,被ParentA.vue引用,过一段时间ParentB.vue也需要用到Child.vue但是只能用到里面的80%,另外20%是与Child.vue不一样的,怎么办,难道我要copy Child.vue随便改吧改吧???
    当然也行,但是是不是感觉很low,对你自己也没有长进,这个时候比较好的做法就是把其中公用的80%,提取出来,然后可定制的20%,通过作用域插槽(有值插槽)让父组件来处理,这个时候就比较完美了

    • 第二个场景
    image.png

    看上图我有三个组件A,B,C。C组件又分为组件的上半部分和下半部分
    如果这个时候我们要让组件A和组件C(上)换位置怎么半???
    难道需要重新把组件A复制到C(上),把C(上)复制到A???
    如果你的C组件上半部分与C组件下半部分交互比较少,还ok,如果交互复杂的话,这样做估计又要掉一把头发了
    这个时候我们就可以使用组件分发来做了

    //Child.vue
    <template>
        <div >
            <div >
                <ul class="child-style">
                    <li v-for="fruilt in fruiltsData" :key="fruilt">{{fruilt}}</li>
                </ul>
                <slot name="slot-firstchild"></slot>
                <slot name="slot-secondchild"></slot>
                <ul class="child-style">
                    <li v-for="animal in animalsData" :key="animal">{{animal}}</li>
                </ul>
            </div>
        </div>
    </template>
    fruiltsData: ['apple','banana','orange'],
    animalsData: ['dog','cat','pig']
    
    //Parent.vue
    <template>
        <div>
            <Child1>
                <Child3 slot="slot-firstchild"></Child3>
                <Child2 slot="slot-secondchild"></Child2>
            </Child1>
    
        </div>
    </template>
    

    //效果图


    image.png

    除了列举的两个场景,solt还有不少别的用法,由于篇幅的原因,下次再讲把。。。

    相关文章

      网友评论

          本文标题:vue slot

          本文链接:https://www.haomeiwen.com/subject/hcknbftx.html