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