【vue(2)插槽】

插槽 --适用于父组件访问子组件

一、概念

1.概念

  • Slot 通俗的理解就是"占坑",在组件模板中占好了位置,当使用该组件标签的时候,组件标签里面的内容就会自动填坑(替换组件模板中slot位置)
  • 并且可以作为承载分发内容的出口

2.作用

允许你在使用组件时向组件内部插入内容(HTML、组件、甚至是函数),让组件可以根据这些内容进行渲染。

3.本质

  • 插槽是 Vue 提供的一个"内容占位符"。
  • 父组件可以向这个"占位符"中插入任意内容
  • 子组件可以决定这些内容在哪里显示

二、插槽的基本使用

  • 插槽就是"占一个位置",等别人来填内容
  • 就像写了一个组件,里面留了一个空位,别人用这个组件的时候,可以自己决定空位放什么内容

举例来说,这里有一个 <FancyButton> 组件

js 复制代码
<FancyButton>
  Click me! <!-- 插槽内容 -->
</FancyButton>

<FancyButton> 的模板是这样的

js 复制代码
<button class="fancy-btn">
  <slot></slot> <!-- 插槽出口 -->
</button>

<slot> 元素是一个插槽出口 (slot outlet),标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。

最终渲染出的 DOM 是这样:

js 复制代码
<button class="fancy-btn">Click me!</button>

三、插槽的分类

名称 说明
默认插槽 插入内容,不指定名字
具名插槽 插入内容,指定名字
作用域插槽 插槽内容可以访问子组件的数据

1.默认插槽

我们要在页面显示三个类别,每个类别下面有不同的文字,本来是我们把数据传给子组件然后使用v-for遍历生成的文字信息,但是产品经理突然让你把美食类的下面换成图片,电影类下面换成视频,怎么搞?

子组件:

js 复制代码
<template>
    <div class="category">
        <h3>{{ title }}类</h3>
        <ul>
            <slot>我是一个插槽,当使用者没有传递具体结构时,我会出现</slot>
        </ul>
    </div>
</template>

父组件App.vue:

js 复制代码
<template>
    <div class="container">
        <Category title="美食">
        <!--往slot插入东西-->
            <img src="http://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
        </Category>
        <Category title="游戏">
         <!--往slot插入东西-->
            <li v-for="(game, index) in games" :key="index">
                {{ game }}
            </li>
        </Category>
        <Category title="电影">
         <!--往slot插入东西-->
            <video controls src="http://clips.vorwaerts-gmbh.de/big_buck.bunny.mp4"></video>
        </Category>
    </div>
</template>

<script>
import Category from './components/Category.vue';

export default {
    name: "App",
    components: { Category },
    data() {
        return {
            //foods: ['火锅', '烧烤', '小龙虾', '牛排'],
            games: ['战神4', '极品飞车', '鬼泣', '超级玛丽'],
           // films: ['《教父》', '《复仇者联盟》', '《绿皮书》', '《阿甘》']
        }
    },
}
</script>

2.具名插槽

子组件使用name属性起个名,父组件里面使用slot="名字"找到对应的坑位

html 复制代码
  父组件中:
	  <template>
	  	<div>
	          <Category>
	              <div slot="center">中间的结构</div>
	              <a slot="center" href="http://www.zzy.com">中间的结构</a>
	  
	              <template v-slot:footer>  最新写法,要配合template使用
	                 <div>底部的结构</div>
	                 <h4>欢迎你</h4>
	              </template>
	          </Category>
	    </div>
	 </template>
 
  子组件中:
        <template>
            <div>
               <!-- 定义插槽 -->
               <slot name="center">插槽默认内容...</slot>
               <slot name="footer">插槽默认内容...</slot>
            </div>
        </template>

3.作用域插槽

有一天,产品经理让你把每个部分的数据换个形式,换成下边这样,咋整?

这里就用到了作用域插槽,如果数据不在App中了,而在Category.vue中,然后App.vue要用到数据,这时我们就可以在Category.vue中使用slot标签给父组件App传值,写法很像当时父给子传值的props写法,在标签里搞个:games="games",然后用到插槽的地方必须使用template标签包裹,并且配置scope属性来接收数据,接过来的是一个对象

其实这个功能使用默认插槽完全可以实现,但是默认插槽是指数据在使用插槽的文件里的,那么如果数据在别的地方(比如本案例的Category.vue文件),就得用作用域插槽

html 复制代码
Category.vue文件
<template>
    <div class="category">
        <h3>{{ title }}类</h3>
        <slot :games="games">默认内容</slot>
    </div>
</template>

<script>
export default {
    name: 'Category',
    props: ['title'],
    data() {
        return {
            games: ['战神4', '极品飞车', '鬼泣', '超级玛丽']
        }
    },
};
</script>
html 复制代码
App.vue文件
<template>
    <div class="container">
        <Category title="游戏">
            <template scope="youxis">
                <!-- {{ youxis.games }} -->
                <!-- { "games": [ "战神4", "极品飞车", "鬼泣", "超级玛丽" ] } -->
                <ul>
                    <li v-for="(game, index) in youxis.games" :key="index">
                        {{ game }}
                    </li>
                </ul>
            </template>
        </Category>

        <Category title="游戏">
            <template scope="{games}">
                <ol>
                    <li v-for="(game, index) in games" :key="index">
                        {{ game }}
                    </li>
                </ol>
            </template>

        </Category>
        <Category title="游戏">
            <template slot-scope="{games: youxis}">
                <h4 v-for="(game, index) in youxis" :key="index">
                    {{ game }}
                </h4>
            </template>
        </Category>
    </div>
</template>

<script>
import Category from './components/Category.vue';
export default {
    name: "App",
    components: { Category },
}
</script>
相关推荐
San306 小时前
JavaScript 流程控制与数组操作全解析:从条件判断到数据高效处理
javascript·面试·代码规范
dengzhenyue6 小时前
矩形碰撞检测
开发语言·前端·javascript
Q_Q5110082856 小时前
python+springboot+uniapp基于微信小程序的停车场管理系统 弹窗提示和车牌识别
vue.js·spring boot·python·django·flask·uni-app·node.js
麦麦大数据7 小时前
D017 vue+django+neo4j音乐知识图谱推荐可视化分析系统|带管理员角色+爬虫
vue.js·数据分析·django·知识图谱·neo4j·推荐算法
前端伪大叔7 小时前
第13篇:🎯 如何精准控制买入卖出价格?entry/exit\_pricing 实战配置
javascript·python
麦当_7 小时前
ReAct 模式在 Neovate 中的应用
前端·javascript·架构
itslife7 小时前
vite源码 - 开始
前端·javascript
Achieve - 前端实验室7 小时前
【每日一面】React Hooks闭包陷阱
前端·javascript·react.js
Asort7 小时前
JavaScript设计模式(四)——建造者模式:优雅构建复杂对象的实用指南
前端·javascript·设计模式