Vue.js中的插槽

  1. 匿名插槽
  2. 具名插槽
  3. 作用域插槽

Question:

1.具名插槽与匿名插槽的区别?

同一个组件,不同的用户调用时渲染的内容不一样,在调用组件时通过slot的name来区分插槽,这个就是具名插槽的作用,而不传值不去指明slot的name值时,这个会调用组件的匿名插槽来渲染组件,可以理解为使用默认值来渲染。

2.作用域插槽是什么意思?

作用域插槽---乍听起来,是一个很抽象的概念。看了几遍官方文档,有了一些粗浅的认识,觉得这个名字取得还挺恰当的,因为它在一定范围内,延伸了子组件的作用域

组件有编译作用域---父级模板里的所有内容都是在父级作用域中编译的,子模板里的所有内容都是在子作用域中编译的。

看看官方的例子---

定义一个子组件,有个具名插槽son,并且通过属性绑定子组件的数据user。

const sonCom = {
      template: `
      <div>
        <slot name="son" :user="user">子组件数据:{{user.firstName}}</slot>
      </div>
      `,
      data() {
        return {
          user: {
            firstName: '三',
            lastName: '张'
          }
        }
      }
    }

父组件调用子组件时,假设不想展示firstName了,想展示lastName,按照下面这样写是不行的。

  <div id="app">
    <son-com>{{user.lastName}}</son-com>
  </div>

因为user是在子组件的作用域中,父组件无法访问。

此时通过作用域插槽,可以做到。如下代码,通过v-slot指定绑定具名插槽son,通过自定义的scope接收子组件的user数据。

(注:v-slot指令是Vue2.6之后,作用域插槽的新语法,旧语法现在还保留,但3.0之后会移除。推荐新语法,简便写法是#son=“{user}”)

  <div id="app">
    <son-com v-slot:son="scope">{{scope.user.lastName}}</son-com>
  </div>

从结果来看,可以认为作用域插槽延伸了子组件数据的作用范围,这样想,作用域插槽这个名字就不那么抽象了,而且顾名思义。

使用场景

例如,在使用elementUI组件库的表格组件时,表格的编辑和删除操作要用到作用域插槽。因为一个表格组件,就是当前组件的子组件。

此时我们通过作用域插槽很容易拿到当前表格行的索引和内容,这样就可以很方便地进行编辑展示、删除的操作。

并且,我们知道Vue是单向数据流。传递给子组件的数据,若要修改,应在父组件中处理。而我们通过作用域插槽,正好可以在父组件中修改数据,方便安全。

摘抄链接如下:简单理解Vue中的作用域插槽 - 思来享趣的文章 - 知乎 https://zhuanlan.zhihu.com/p/255241094

子组件:

<template>
   <div :class="['my-btn',btnStyle]">
    {{btnText}} 
    <div>
         <!--匿名slot -->
        <slot></slot>
        <!-- 具名slot -->
        <slot name="slot1"></slot>
       <slot name="slot2" ></slot>
        <slot name="childSlot" :data="data">
         </slot>
    </div>
   </div>
 
</template>

<script>
export default {
  
  props:{
    btnStyle:String,
    btnText:String
  },
 
  data () {
    return {
      data:['1','2','3'],
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>
<style>
 .my-btn{
     height:34px;
     padding:0 15px;
     border-radius: 5px;
     border:none;
     outline: none;
     background-color: aliceblue;
 }
 .btn-warning{
     background: red;
 }
</style>

父组件:

 

<template>
  <div id="app">
       <h1>vue中插槽的实际应用</h1>
       <my-button btnStyle='btn-warning' btnText='这是btnText'>
       </my-button >

   <!-- 匿名插槽 -->
       <div :style="{background:'gray','margin-top':'50px'}">
          <my-button>
          <div>我是匿名slot</div>
          </my-button>
       </div>
    <!-- 具名插槽 -->
       <div :style="{background:'gray','margin-top':'50px'}">
          <my-button>
          <template v-slot:slot2>
            <div style="background-color:gray">这是具名slot-2</div>
          </template>
          <template v-slot:slot1>
            <div style="background-color:pink">这是具名slot-1</div>
          </template>
          </my-button>
       </div>
      <!-- 作用域插槽-用列表展示出来 -->
       <div :style="{background:'gray','margin-top':'50px'}">
          <my-button>
          <template slot="childSlot" slot-scope="slotValue"> 
              <ul>
                <li v-for="(item,index) in slotValue.data" :key="index">{{item}}</li>
                </ul>
          </template>
          </my-button>
       </div>

       
  </div>
</template>

<script>
import  Button from '@/components/Button';
export default {
  
   components:{
       MyButton:Button,
   }

  
}
</script>
<style>

</style>

效果图如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值