0


一文详解Vue插槽slot的使用与案例展示,看完就彻底明白了

插槽 slot 在实际的项目开发中是经常使用的,主要分为三大类:默认插槽具名插槽作用域插槽,也是比较容易上手的。

一、插槽的含义

插槽 **slot **是写在子组件的代码中,供父组件使用的占位符。在代码中,大致写为如下的形式,后面会进行详细的写法介绍。

<slot> </slot>

插槽其实就是在写 **slot **的地方挖个坑,等着组件的使用者,即父组件,进行填充。子组件中使用插槽 **slot **后,父组件可以在这个占位符中填充内容,包括数据、html代码、组件等,也就是说,当子组件的某部分内容是根父组件填充的不同而变化的,那我们就可以使用插槽slot,具体填充什么,由父组件而定。

让父组件向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于父组件 => 子组件

话不多说,下面,我们就来看看 **slot **的具体如何使用吧!

二、插槽的三种使用方法

1.默认插槽

有两个组件,App是父组件,Child是子组件

父组件代码如下:

<template>
  <div class="parent">
    <span>我是父组件</span>
    <Child></Child>
  </div>
</template>

<script>
import Child from './components/Child'
export default {
  name:'app',
  components:{
    Child
  }

}
</script>

<style scoped>
.parent{
  width: 400px;
  height: 400px;
  background-color: #bfa;
}
</style>

子组件的代码:

<template>
  <div class="child">
    <div>我是子组件</div>
    <br>
    <slot>我是默认插槽,当父组件不填充任何内容时,我这句话才会出现</slot>
  </div>
</template>

<script>
export default {
  name:'Child',
  data() {
    return {
      
    }
  },
};
</script>

<style>
.child {
  width: 200px;
  height: 200px;
  background-color: lightblue;
  margin: auto;
}
</style>

启动项目,在浏览器中显示:

这时候,我们已经使用 **slot **,在子组件中占了一个坑,但是我们还没有填充内容,接下来填充内容:

可以看到,填充的内容,确实在子组件中显示

假如,我们去掉子组件的插槽,父组件在子组件填充的内容还能看到吗?我们来试一试:

可以看到:浏览器中,只显示两个组件原本的信息,父组件填充的内容是看不到的。

在 **slot **中,不仅可以填充文字,也可以填充图片、视频、HTML结构等,如填充图片:

浏览器中显示如下:

2.具名插槽

具名插槽,顾名思义,就是带有名字的插槽,具有 **name **属性,一个不带 name 的 **

<

slot

>

**会带有默认的名字 default

在子组件中,**slot **指定 **name **属性

<template>
  <div class="child">
    <div>我是子组件</div>
    <br>
    <slot name="content">
      我是插槽默认的内容,当父组件不填充任何内容时,我这句话才会出现
    </slot>
  </div>
</template>

<script>
export default {
  name:'Child',
  data() {
    return {
      
    }
  },
};
</script>

<style>
.child {
  width: 200px;
  height: 200px;
  background-color: lightblue;
  margin: auto;
}
</style>

在父组件中,需要使用 **template **,在 **template **模板中,指定 **slot **在子组件中的 name

<template>
  <div class="parent">
    <span>我是父组件</span>
    <Child>
      <template slot="content">
        <div>这是父组件在子组件中填充的内容,在子组件中显示</div>
        <br />
        <img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="" />
      </template>
    </Child>
  </div>
</template>

<script>
import Child from "./components/Child";
export default {
  name: "app",
  components: {
    Child,
  },
};
</script>

<style scoped>
.parent {
  width: 400px;
  height: 400px;
  background-color: #bfa;
}
img {
  width: 200px;
}
</style>

浏览器可以正常显示填充的内容:

假如,我们在父组件中,只写了 **template **,并没有指定 **slot **在子组件中的 **name **值,

那么,浏览器中:

也就是说,在引用子组件的代码中, **template 中的slot **是根据等号 **= **后面的值,来寻找对应的插槽 **slot **,从而在对应的位置上,填充相应的内容。当我们使用的插槽数量比较多时,具名插槽就有很大的实用性。

3.作用域插槽

如果数据在子组件,可以在子组件中直接使用数据,但根据数据生成的结构需要组件的使用者来决定,我们就需要用到作用域插槽,同时,我们也可以实现多种结构。

例如:games数据在子组件中,但使用数据所遍历出来的结构由父组件App决定

子组件中,使用 **<slot :games="games"> **指明使用什么数据,并将数据传给插槽的使用者

<template>
  <div class="child">
    <span>我是子组件</span>
    <h5>{{title}}</h5>
    <slot :games="games">
      我是插槽默认的内容,当父组件不填充任何内容时,我这句话才会出现
    </slot>
  </div>
</template>

<script>
export default {
  name:'Child',
  props:['title'],
  data() {
    return {
      games:['红色警戒','穿越火线','超级玛丽'],
    }
  },
};
</script>

<style>
.child {
  width: 200px;
  height: 200px;
  background-color: lightblue;
  margin: auto;
}
</style>

在父组件中,使用子组件通过插槽传递过来的数据,渲染结构,有3种形式:

<template>
  <div class="parent">
    <span>我是父组件</span>
    <Child title="游戏1">
            <template scope="youxi1">
        <!-- 无序列表结构 -->
                <ul>
                    <li style="color:red" v-for="(g,index) in youxi1.games" :key="index">{{g}}</li>
                </ul>
            </template>
        </Child>
    <hr>
    <Child title="游戏2">
      <template slot-scope="youxi2">
        <!-- 有序列表结构 -->
        <ol>
          <li v-for="(g,index) in youxi2.games" :key=index>{{g}}</li>
        </ol>  
      </template>
    </Child>
    <hr>
    <Child title="游戏3">
      <template scope="{games}">
        <!-- h4结构 -->
        <h5 v-for="(g,index) in games" :key=index>{{g}}</h5>
      </template>
    </Child>
    <hr>
  </div>
</template>

<script>
import Child from "./components/Child";
export default {
  name: "app",
  components: {
    Child,
  },
};
</script>

<style scoped>
.parent {
  width: 400px;
  height: 700px;
  background-color: #bfa;
}
img {
  width: 200px;
}
</style>

浏览器中:

第1种:是基本用法,使用 **scope = " youxi1 ",youxi1 **是自定义的变量,来接收子组件传过来的数据,它是一个对象,使用插值语法,把 **youxi1 **打印出来:

第2种:将 **scope **替换为 slot-scope

第3种:使用 es6 解构赋值的方法,直接将对象数据解构为数组,然后进行 **v-for **的遍历

上述的小案例,就实现了:使用同样的数据,父组件将其渲染成不同的结构,非常方便实用。

4.版本变化

** Vue 2.6.0 **起,引入了 v-slot ,上文提到了3类插槽的 **slot 和 slot-scope **,可以直接替换为 **v-slot **,在vue2版本中,我们仍可以使用 **slot slot-scope **,但是在vue3中就只能使用v-slot了。详细内容参见 vue官方文档 的解释。


本文转载自: https://blog.csdn.net/czjl6886/article/details/122094040
版权归原作者 唯一的阿金 所有, 如有侵权,请联系我们删除。

“一文详解Vue插槽slot的使用与案例展示,看完就彻底明白了”的评论:

还没有评论