插槽的使用

156 阅读2分钟

插槽的用处

  • 让父组件可以向子组件的的指定位置,插入 HTML 结构,也属于一种组件通信方式,适用于 父组件 ===> 子组件

分类

  • 默认插槽、具名插槽、作用域插槽

默认插槽

使用场景

  • 在父组件中,有多个调用者调用同一个子组件,但是各自的展示效果都不同

20210811215648.png

说说怎么用

  • 在父组件的子组件中

    xxxx

  • 根据每个子组件的需求写相关逻辑

在父组件和子组件写样式,有什么区别

  • 如果在父组件中,写好相关子组件的样式;则会将模板解析好了,再放入子组件的插槽
  • 如果在子组件中,写好相关样式,则会将模板放入子组件的插槽之后,再解析

插槽的默认值

我是一些默认值,当使用者没有传递具体结构时,我会出现

代码实现

App.vue

<template>
    <div class="container">
        <Category title="美食" >
            <img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
        </Category><Category title="游戏" >
            <ul>
                <li v-for="(g,index) in games" :key="index">{{g}}</li>
            </ul>
        </Category><Category title="电影">
            <video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
        </Category>
    </div>
</template><script>
    import Category from './components/Category'
    export default {
        name:'App',
        components:{ Category },
        data() {
            return {
                foods:['火锅','烧烤','小龙虾','牛排'],
                games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
                films:['《教父》','《拆弹专家》','《你好,李焕英》','《尚硅谷》']
            }
        },
    }
</script>

Category.vue

<template>
    <div class="category">
        <h3>{{ title }}分类</h3>
        <!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) -->
        <slot>我是一些默认值,当使用者没有传递具体结构时,我会出现</slot>
    </div>
</template><script>
    export default {
        name:'Category',
        props:['title']
    }
</script>

具名插槽

使用场景

  • 子组件需要使用多个插槽

20210811221628.png

说说怎么用

  • 给每个插槽 和 要放入插槽的 DOM 元素,都加上对应的名字

有一个关于 template 的坑

  • 最新的命名方法,只能用于template

    v-slot:footer

代码实现

App.vue

<template>
    <div class="container">
        <Category title="美食" >
            <img slot="conter" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
            <a slot="footer" href="http://www.atguigu.com">更多美食</a>
        </Category><Category title="游戏" >
            <ul slot="center">
                <li v-for="(g,index) in games" :key="index">{{g}}</li>
            </ul>
            <div class="foot" slot="footer">
                <a href="http://www.atguigu.com">单机游戏</a>
                <a href="http://www.atguigu.com">网络游戏</a>
            </div>
        </Category><Category title="电影">
            <video slot="center" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
            <template v-slot:footer>
                <div class="foot">
                    <a href="http://www.atguigu.com">经典</a>
                    <a href="http://www.atguigu.com">热门</a>
                    <a href="http://www.atguigu.com">推荐</a>
                </div>
                <h4>欢迎前来观影</h4>
            </template>
        </Category>
    </div>
</template><script>
    import Category from './components/Category'
    export default {
        name:'App',
        components:{Category},
        data() {
            return {
                foods:['火锅','烧烤','小龙虾','牛排'],
                games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
                films:['《教父》','《拆弹专家》','《你好,李焕英》','《尚硅谷》']
            }
        },
    }
</script>

Category.vue

<template>
    <div class="category">
        <h3>{{title}}分类</h3>
        <!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) -->
        <slot name="center">我是一些默认值,当使用者没有传递具体结构时,我会出现1</slot>
        <slot name="footer">我是一些默认值,当使用者没有传递具体结构时,我会出现2</slot>
    </div>
</template><script>
    export default {
        name:'Category',
        props:['title']
    }
</script>

作用域插槽

使用场景

  • 数据在子组件(接受插槽的组件),并且不能在父组件定义(定义插槽的组件)

image.png

说说怎么用

  • 子组件通过插槽将数据传给父组件,父组件如下方法接收,再使用

    也可以使用 ES6语法的解构赋值接收

代码实现

App.vue

<template>
    <div class="container"><Category title="游戏">
            <template scope="atguigu">
                <ul>
                    <li v-for="(g,index) in atguigu.games" :key="index">{{g}}</li>
                </ul>
            </template>
        </Category><Category title="游戏">
            <template scope="{games}">
                <ol>
                    <li style="color:red" v-for="(g,index) in games" :key="index">{{g}}</li>
                </ol>
            </template>
        </Category><Category title="游戏">
            <template slot-scope="{games}">
                <h4 v-for="(g,index) in games" :key="index">{{g}}</h4>
            </template>
        </Category>
    </div>
</template><script>
    import Category from './components/Category'
    export default {
        name:'App',
        components:{ Category },
    }
</script>

Category.vue

<template>
    <div class="category">
        <h3>{{title}}分类</h3>
        <slot :games="games" msg="hello">我是默认的一些内容</slot>
    </div>
</template><script>
    export default {
        name:'Category',
        props:['title'],
        data() {
            return {
                games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
            }
        },
    }
</script>