Vue中的插槽

Vue 插槽

文章目录

  • Vue 插槽
      • 01-插槽-默认插槽
          • 默认插槽-基本语法
      • 02-插槽-后备内容(默认值)
          • 默认值设置方法
      • 03-插槽-具名插槽
          • 具名插槽-语法
      • 04-插槽-作用域插槽
          • 默认插槽-语法
          • 代码示例

插槽的作用:让组件内部的一些 结构 支持自定义。

例如:我们需要再页面中显示一个对话框,将其封装成一个组件。

当我们希望组件内容部分,不希望写死,就得用插槽来解决

插槽的分类:

  1. 默认插槽: 组件内定制一处结构
  2. 具名插槽:组件内定制多处结构
    • 作用于插槽:是插槽的一个传参语法

01-插槽-默认插槽

默认插槽-基本语法
  1. 组件内需要定制的结构部分,使用占位
  2. 使用组件时,标签内部,传入结构替换slot。

基本使用

MyDialog组件
1.组件内需要定制的结构部分,使用<slot></slot>占位

    <div class="dialog-content">
      <!-- 1. 在需要定制的位置,使用slot占位 -->
        <slot></slot>
    </div>



App.vue组件
2.使用组件时,<MyDialog></MyDialog>标签内部,传入结构替换slot。

  <div class="app">
    <!-- 2. 在使用组件时,组件标签内填入内容 -->
    <MyDialog>
      <div>你确认要退出么</div>
    </MyDialog>
    <MyDialog>
      <p>你确认要删除吗</p>
      <p>你确认要删除吗</p>
      <p>你确认要删除吗</p>
    </MyDialog>
  </div>


02-插槽-后备内容(默认值)


通过插槽完成了内容的定制,传什么显示什么,但是如果我们在组件使用的时候,不传,则是空白

那么能否给插槽设置 默认显示内容呢?

默认值设置方法
  • **语法:**在标签内,放置内容,这里面的内容会被默认显示。
  • 当组件使用时传给了内容则不会显示标签里面的默认内容
MyDialog组件
1.
    <div class="dialog-content">
      <!-- 往slot标签内部,编写内容(会被作为后备默认内容) -->
        <slot>我是默认的插槽内容</slot>
    </div>

App.vue组件
  <div class="app">
      //一个不传值,一个传值
    <MyDialog></MyDialog>

    <MyDialog>
      我传递了内容哦!
    </MyDialog>
  </div>

说白了就是当不给组件传值的时候,就显示slot标签内部的内容。


03-插槽-具名插槽


当一个组件有多个结构,需要进行定制内容

此时的默认插槽是无法解决该问题

默认插槽:只能有一个定制位置

所以,得使用具名插槽来解决


具名插槽-语法
  1. 使用多个 slot 标签 ,并且使用 name 属性区分名字
  2. template配合 v-slot:名字 来分发对应标签
  3. 简写:v-slot:插槽名 → 可以简写为 #插槽名

MyDialog组件
1. 
<div class="dialog-header">
      <!-- 一但插槽起了名字,就是具名插槽,(只支持定向分发) -->
      <slot name="head"></slot>
    </div>
    <!-- 内容 -->
    <div class="dialog-content">
        <slot name="content"></slot>
    </div>
    <!-- 底部 -->
    <div class="dialog-footer">
      <slot name="footer"></slot>
    </div>


App.vue组件
2.切记用template包裹起来,根据插槽名分发内容

    <MyDialog>
      <!-- 需要通过template包裹,template配合 v-slot:名字 来分发对应标签 -->
      <template v-slot:head>
        <div>我是大标题</div>
      </template>

      <template v-slot:content>
        <div>我是内容</div>
      </template>
      <!-- 简写#插槽名 -->
      <template #footer>
        <button>确认</button>
        <button>取消</button>
      </template>
    </MyDialog>


04-插槽-作用域插槽


作用于插槽:定义slot插槽的同时,是可以传值的。给 插槽 上可以 绑定数据,将来 使用组件时可以使用。


使用场景:封装表格组件

  1. 父传子,动态渲染表格内容
  2. 利用默认插槽,定制操作列表
  3. 删除或查看都需要用到 当前项 的 id ,数组组件内部数据(通过作用域插槽 传值绑定,进而使用)

默认插槽-语法
  1. 给 slot 标签 ,以添加属性的方式传值

  1. 所有添加的属性,都会被收集到一个对象中

    { id: 3 , msg: '测试'}

  2. 在 template中,通过 #插槽名="obj"接收,默认插槽名为: default → #default="obj"


这里使用一个简单的表格删除和查询来练习插槽

代码示例

首先是我们呢的子组件代码

<template>
  <table class="my-table">
    <thead>
      <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>年纪</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(item,index) in data" :key="item.id">
        <td>{{ index + 1 }}</td>
        <td>{{ item.name }}</td>
        <td>{{ item.age }}</td>
        <td>
          
          <!-- 定义插槽的同时,可以传值哦(使用插槽作用域) -->
          <!-- 1. 给slot标签,添加属性的方式传值 -->
          <slot :row="item" msg="测试">默认插槽</slot>

          <!-- 2. 将所有的属性添加到一个对象中 -->
          <!-- 
                {
                  row : {id: 2 ,name: "孙大明", age: 19},
                  msg: '测试文本'
                }
           -->
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script>
export default {
props: {
  data: Array
}
}
</script>

App.vue父组件代码

<template>
  <div>
    <MyTable :data="list">
      <!-- 3. 通过template #插槽名="变量名" 接收 -->
      <template #default = "obj">
        <button @click="del(obj.row.id)">删除</button>
      </template>
    </MyTable>
    
    <MyTable :data="list2">
      <!-- 这里是一样的:需要使用template包裹 -->
      <template #default="{row}">
        <button @click="look(row)">查看</button>
      </template>
    </MyTable>
  </div>
</template>

<script>
import MyTable from './components/MyTable.vue'
export default {
  data () {
    return {
      list: [
        { id: 1, name: '张小花', age: 18 },
        { id: 2, name: '孙大明', age: 19 },
        { id: 3, name: '刘德忠', age: 17 },
      ],
      list2: [
        { id: 1, name: '赵小云', age: 18 },
        { id: 2, name: '刘蓓蓓', age: 19 },
        { id: 3, name: '姜肖泰', age: 17 },
      ]
    }
  },
  methods: {
    del (id) {
      // 删除功能:使用filter过滤
      this.list = this.list.filter( item => item.id !== id)
    },
    look (row) {
      alert(`姓名:${row.name};  年纪:${row.age}`)
    }
  },
  components: {
    MyTable
  }
}
</script>

Vue中的插槽_第1张图片

这里主要讲解了插槽的语法和基本的使用。


你可能感兴趣的:(Vue,vue.js,前端,javascript)