【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>
相关推荐
PyHaVolask15 分钟前
HTML 表单进阶:用户体验优化与实战应用
前端·javascript·html·用户体验
花菜会噎住2 小时前
Vue3核心语法进阶(computed与监听)
前端·javascript·vue.js
花菜会噎住2 小时前
Vue3核心语法基础
前端·javascript·vue.js·前端框架
全宝2 小时前
echarts5实现地图过渡动画
前端·javascript·echarts
练习前端两年半4 小时前
Vue3 源码深度剖析:有状态组件的渲染机制与生命周期实现
前端·vue.js
吃饭睡觉打豆豆嘛4 小时前
彻底搞懂前端路由:从 Hash 到 History 的演进与实践
前端·javascript
lbh5 小时前
简单文本编辑器:基于原生JavaScript的智能文本选择工具栏
前端·javascript
典学长编程5 小时前
前端开发(HTML,CSS,VUE,JS)从入门到精通!第三天(JavaScript)
前端·javascript·css·html·前端开发
533_7 小时前
[vue3 echarts] echarts 动态数据更新 setInterval
vue.js·echarts