如何理解vue中slot插槽

最开始接触或者注意这个东西,是在用elementUI做后台管理系统时,对列表组件中某些特定的列做修改或判断时会用到。在template中有个slot-scope="scope",当时只是知道怎么用,知其然不知其所以然。

<el-table v-loading="loading" :data="tableList">
  <el-table-column prop="name" label="名称" />
  <el-table-column prop="status" label="状态">
    <template slot-scope="scope">
      <span v-if="scope.row.status===0">未完成</span>
      <span v-if="scope.row.status===1">已完成</span>
      <span v-if="scope.row.status===2">已启用</span>
    </template>
  </el-table-column>
</el-table>

回头仔细研究了一番,总结就一句话:在vue的模块化设计中,为子组件进行赋能。为何这样说:

聚个例子,我们现在封装了一个移动端列表的行展示组件zd-item,其样式和功能覆盖了大部分的需求,但是对一些特殊的行,我们要进行样式的调整和功能的修改,显然为这一个特殊的行通过props传值的方式修改样式或$emit的方式多加一个事件也是不值得,重新封装一个类似组件更是没必要的,这个时候我们就需要为我们的行组件赋能,让其支持在父组件中使用时可以自定义内容及样式和事件。

首先我们来定义子组件

<template>
  <div class="child">
    <!--slot起到一个占位的作用 在父组件中引用时可修改同位置的内容-->
    <!--slot的两外一个作用 将子组件的值传给父组件 让其使用-->
    <slot :childName="'子组件修改后的'+childItem.name">{{childItem.name}}</slot>
    <button @click="clickChild">点击子组件</button>
  </div>
</template>

<script>
  export default {
    name: "child",
    props: {
      childItem: {
        type: Object,
        default: {},
      },
    },
    methods: {
      clickChild() {
        console.log('我是子的方法')
      },
    },
  }
</script>

<style scoped>
  .child{
    display: flex;
    justify-content: space-between;
  }
</style>

然后在父组件中使用子组件

<template>
  <div>
    <child :key="index" v-for="(item,index) in list" :childItem="item">
      <!--因为子组件使用了slot占位 所以在这里可以用template修改子组件同位置的内容-->
      <!--由于子组件中通过:childName传递了值 所以这里能通过aaa.childName获取值-->
      <template slot-scope="aaa">
        <span v-if="item.id===3" style="color: red;">{{aaa.childName}}</span>
      </template>
    </child>
  </div>
</template>

<script>
  import child from './child'
  export default {
    name: "father",
    components:{
      child,
    },
    data(){
      return{
        list:[
          {id:1,name:'张三'},
          {id:2,name:'李四'},
          {id:3,name:'王五'},
        ]
      }
    },
  }
</script>

插槽分为三种:匿名插槽、具名插槽、作用域插槽。

上面提到的时作用域插槽,其核心作用时占位和传值。

接下来我们看看另外两种插槽:匿名插槽和具名插槽

<!-- 子组件 -->
<template>
  <div class="child">
    <slot><!-- 我是子组件提供的空占位符 可以在这里插入值 --></slot>
    <slot>我是子组件提供的默认值 可修改我</slot>
  </div>
</template>

<!-- 父组件 -->
<template>
  <div class="father">
    <child>
      <span>你提供了占位符 那我就选择性的 给你插个值吧</span>
      <span>你有默认值 但用的slot占位符 我就可以修改你</span>
    </child>
  </div>
</template>

像上面这种只是提供了占位符,不牵扯数据传递的slot方式,我们就称其为匿名插槽,也可以叫单个插槽或者默认插槽。与之相对的,是具名插槽。具名插槽的使用场景是什么呢?

以上面代码为案例,我们在父组中只想修改值而不想插入值,但是当在父组件中template里设置单个值时并不能达到修改的目的,因为没有任何标识,子组件默认就会指到第一个slot的位置,这是我们就用到了具名插槽,给支持修改的slot加个name="center",然后在父组件中用v-slot:center指向要修改的位置。

<!-- 子组件 -->
<template>
  <div class="child">
    <slot><!-- 我是子组件提供的空占位符 可以在这里插入值 --></slot>
    <slot name="center">我是子组件提供的默认值 可修改我</slot>
  </div>
</template>

<!-- 父组件 -->
<template>
  <div class="father">
    <child>
      <template v-slot:center>
        <span>我用v-slot具名插槽指向了子组件中的center位置</span>
      </template>
    </child>
  </div>
</template>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值