vue插槽(slot)的理解

简述

vue提供的插槽功能,实现了在 使用子组件时,为子组件提供结构 的功能。

比如,封装对话框组件的时候,对话框内容是什么?标题又是什么?

这些不确定的内容应该由使用者(父组件)提供才对。这时,就需要用插槽功能


 插件的基本语法

  •  (子组件全局注册过)

上述,定义子组件(对话框组件)的时候,我们希望使用者(父组件)在使用按钮组件的时候,为其提供结构,所以

  • 子组件:在<div class="dialog"></div>内使用一对<slot>标签占位。表示这里要放一些内容,相当于在这里挖了一个坑位,准备存储内容
  • 父组件:使用子组件的时候,在标签中间,为插槽(前面的坑位),传递内容

具名插槽

上述介绍了插槽的基本用法。也就是默认插槽

槽还有另外两种情况,分别是

  • 具名插槽(具有名字的插槽)
  • 作用域插槽(插槽可以为父组件提供数据)

下面先看具名插槽:

 


 作用域插槽

有些时候,子组件在定义插槽的时候,需要向使用者(父组件)传递一些数据,这样的插槽叫做作用域插槽。

<template>
  <div>
    <h2>App组件</h2>
    <MyDialog>
      <!-- 标签内的所有代码,都是给插槽传递的结构 -->
      <!-- <template v-slot:title="obj"> -->
      <template v-slot:title="{ uname, age }">
        <!-- 接收到的值,只能在当前的template里面用,所以这类插槽叫做 作用域插槽 -->
        添加学员 {{ uname }} {{ age }}
      </template>
    </MyDialog>
  </div>
</template>

<script>
import MyDialog from './components/MyDialog.vue'
export default {
  components: { MyDialog },

}
</script>

子代码组件

<template>
  <div class="dialog">
    <!-- 使用 slot 标签,站位,表示这里要放页面结构 -->
    <h3>
      <!-- 只要包含有除name以外的其他属性的插槽,叫做作用域插槽 -->
      <slot name="title" uname="zs" age="20">标题</slot>
    </h3>
  </div>
</template>

<style>
.dialog {
  padding: 5px;
  margin: 10px;
  border: solid 2px black;
  border-radius: 5px;
  box-shadow: 5px 5px 2px 2px;
}
</style>

案例(补充说明)

父组件有一些数据,需要传给子组件,然后遍历展示,并且做删除效果。

父组件代码:

<template>
  <div>
    <h2>列表数据</h2>
    <my-list :list="list">
      <template #default="{ id }">
        <button @click="del(id)">删除</button>
      </template>
    </my-list>

    <my-list :list="goods">
      <template #default="{ id }">
        <button>编辑</button>
        <button>查看详情</button>
        <button @click="delGoods(id)">删除</button>
      </template>
    </my-list>
  </div>
</template>

<script>
import MyList from './components/MyList.vue'
export default {
  components: { MyList },
  data () {
    return {
      list: [
        { id: 2, name: "关羽" },
        { id: 4, name: "张飞" },
        { id: 5, name: "赵云" },
        { id: 7, name: "黄忠" },
        { id: 8, name: "马超" },
      ],
      goods: [
        { id: 2, name: "方便面" },
        { id: 4, name: "鸡爪子" },
        { id: 5, name: "火腿肠" },
        { id: 7, name: "大辣条" },
        { id: 8, name: "卤鸡蛋" },
      ]
    }
  },
  methods: {
    del (id) {
      // console.log('做删除', id)
      this.list = this.list.filter(item => item.id != id)
    },
    delGoods (id) {
      this.goods = this.goods.filter(item => item.id != id)
    }
  }
}
</script>

子组件 MyList.vue (注意:动态传的数据名称保持一致)

<template>
  <div>
    <h2>列表数据</h2>
    <my-list :list="list">
      <template #default="{ id }">
        <button @click="del(id)">删除</button>
      </template>
    </my-list>

    <my-list :list="goods">
      <template #default="{ id }">
        <button>编辑</button>
        <button>查看详情</button>
        <button @click="delGoods(id)">删除</button>
      </template>
    </my-list>
  </div>
</template>

<script>
import MyList from './components/MyList.vue'
export default {
  components: { MyList },
  data () {
    return {
      list: [
        { id: 2, name: "关羽" },
        { id: 4, name: "张飞" },
        { id: 5, name: "赵云" },
        { id: 7, name: "黄忠" },
        { id: 8, name: "诸葛卧龙" },
      ],
      goods: [
        { id: 2, name: "方便面" },
        { id: 4, name: "肉蛋葱鸡" },
        { id: 5, name: "火腿肠" },
        { id: 7, name: "大辣条" },
        { id: 8, name: "土豆片" },
      ]
    }
  },
  methods: {
    del (id) {
      // console.log('做删除', id)
      this.list = this.list.filter(item => item.id != id)
    },
    delGoods (id) {
      this.goods = this.goods.filter(item => item.id != id)
    }
  }
}
</script>

其他补充

子组件,定义默认插槽(<slot>)时

  • 默认插槽 <slot></slot> 插槽其实也有名字,名字是default
  • <slot>可以省略掉 name="default"
  • 可以在 <slot>......</slot> 点点点的位置,设置插槽的默认值

父组件,使用插槽时

  • 使用插槽时,没有被包裹在<template v-slot:xxx>中的内容都会被视为默认插槽的内容
  • 使用插槽时,v-slot:abc可以简写为 #abc
  • 给插槽传递内容的时候,可以将其他组件传进去。

<MyDialog>

<MyTest></MyTest>
</MyDialog>

  • 我们学的是新版的插槽(适用于vue2和vue3)。老版本的插槽参见这里
  • 老版本的 slot 相当于 新版的 v-slot老版本的 slot-scope="obj" 相当于 新版的 v-slot:default="obj" (作用域插槽)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值