vue-使用插槽

前言

上一章说了组件,组件有着很多的特点,灵活、高复用、逻辑分离、专注点分离 ,但时只使用组件通讯好像并不能让组件太灵活,组件之间的通讯只能改变一些参数、变量。那我们如果想要更加灵活的改变组件内的模板展示该怎么办呢?

上一章:初识vue-组件及组件传值 - 掘金 (juejin.cn)

插槽

当我们封装高复用组件的时候,有时候不仅要考虑它内部的一些变量是否要改变,还要考虑这个组件内的模板是否可控,怎么才能定义控制组件内的模板呢?这个时候就要使用到插槽了(slot)

官方解释:

定义使用插槽

定义的时候只需要在子组件内部使用vue内置组件solt来占位即可,使用的时候就是将单标签组件改为双标签,在两个标签内写入的模板就自动映射到子组件内部solt所在的位置了

vue 复制代码
Dialog.vue
子组件  自定义一个弹窗组件
  <div v-show="flag">
    <div><i @click="$emit('chang', false)">X</i></div>
    //父组件调用这个组件,并在两个标签内写入模板就会映射到这里
    <slot></slot>
  </div>
  //组件使用v-mode定义
  export default {
  props: {
    flag: {
      type: Boolean,
      default: false,
    },
  },
  model: {
    prop: "flag",
    event: "change",
  },
};
  父组件
  Home.vue
   <Dialog v-model="flag">
    <img src="xxx.png" alt="" />//如果当我们不写入这个img标签时,弹窗组件除了弹窗外,什么都不会显示
  </Dialog>

插槽默认值

这个就很好理解,就是当我们没有在父组件内传入模板的时候,子组件内定义插槽的位置会默认显示,否者就显示传入映射的模板

vue 复制代码
Dialog.vue  
<template>
  <div v-show="flag">
    <div><i @click="$emit('chang', false)">X</i></div>
    //slot里可以定义任何模板中的数据 slot在解析的时候不会有任何含义
    //当父组件标签内没有传入模板片段,或者使用的是单标签的时候,这里会默认显示,否则显示父组件传入的那内容
    <slot>
      <ul>
        <li>颤三</li>
      </ul>
    </slot>
  </div>
</template>

Home.vue
此时调用子组件显示的就是li标签内的'颤三'
  <Dialog v-model="flag"/>

命名插槽

有些情况在一个组件内可能需要不止一个插槽,当组件内封装有多个插槽的时候,可以使用命名插槽来指定要将显示的内容

只需要在slot上添加name属性即可

父组件指定插槽位置时vue2中使用slot,到vue2.6之后就变为纯正的指令了 v-slot:指定插槽名

vue 复制代码
//子组件
Dialog.vue

<div v-show="flag">
    <div><i @click="$emit('chang', false)">X</i></div>
    //子组件内添加name属性即可 命名插槽一样可以有默认内容
    <slot name="header"> </slot>//这里就是'页眉'
    <br />
    <slot> </slot>//这里就是'内容'
    <hr />
    <slot name="footer"> </slot>//这里就是'页脚'
  </div>

父组件 vue2.6之前

vue 复制代码
Home.vue
<Dialog v-model="flag">
    <template slot="header"> 页眉 </template>
    内容
    <template slot="footer"> 页脚 </template>
</Dialog>

父组件 vue2.6之后

vue 复制代码
Home.vue
//v-slot也可以简写为#  下面v-slot:header === #header
<Dialog v-model="flag">
    //#headrer
    <template v-slot:header> 页眉 </template>
    内容
    //#footer
    <template v-slot:footer> 页脚 </template>
</Dialog>

作为指令 它一样是可以使用动态命名的

使用v-slot:[变量] 或者使用#[变量]

之前有写指令内容:初识vue--基础认识(1) - 掘金 (juejin.cn)

作用域插槽

还有一种情况,我们在父组件内的插槽中需要渲染子组件内部的数据,正常来说是拿不到的。但是在插槽里vue提供了这种写法。当我们在slot上添加除name 属性外的属性,都可以在父元素插上拿到的 官方示意图:

vue 复制代码
子组件内
Dialog.vue

<template>
  <div v-show="flag">
    <div><i @click="$emit('chang', false)">X</i></div>
    //在slot组件上可以是任意属性 参数也可以是动态的
    <slot name="header" :num="1" title="iceCode"> </slot>
    <br />
    <slot title="默认的"> </slot>
    <hr />
    <slot name="footer" :num="+new Date() % 2 === 0 ? true : false"> </slot>
  </div>
</template>

父组件 vue2.6之前

vue 复制代码
Home.vue
<Dialog v-model="flag">
    //可以使用slot-coppe 拿到所要传的参数 
    //此时row={num:1,title:'iceCode'}
    <template slot="header" slot-scope='row'> 页眉 </template>
    //默认插槽会有一个固定的名字 default
    //此时row={title:'默认的'}
    <template slot="default" slot-scope='row'> 内容 </template>
    //这里同理
    <template slot="footer" slot-scope='row'> 页脚 </template>
</Dialog>

父组件 vue2.6之后

vue 复制代码
Home.vue
//v-slot也可以简写为#  下面v-slot:header === #header
<Dialog v-model="flag">
    //这里获得的数据和上面是一致的
    <template #header='row'> 页眉 </template>
    //默认插槽 也是为default
    <template #default='row'> 内容 </template>
    <template #footer='row'> 页脚 </template>
</Dialog>

注意

不管vue2.6之前还是之后,这里插槽里的数据都可以解构使用的

插槽的高阶用法

这里是官方演示的一个高阶用法,作为小菜鸡,本人暂时没有使用过

主要是在使用v-for渲染的时候,item作为一个对象 可以直接使用v-bind动态绑定这些item,key作为属性,value作为属性值通过插槽传递(这种写法有些像react里面利用jsx快速绑定属性名,属性值,不过不用展开)

结尾

插槽的基本使用就这些,学会使用插槽,可以让自己封装更加灵活的组件。高复用,低耦合性的组件离不开组件传值和插槽的

相关推荐
Мартин.1 分钟前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
一 乐1 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
昨天;明天。今天。1 小时前
案例-表白墙简单实现
前端·javascript·css
数云界1 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd2 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常2 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer2 小时前
Vite:为什么选 Vite
前端
小御姐@stella2 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing2 小时前
【React】增量传输与渲染
前端·javascript·面试
eHackyd2 小时前
前端知识汇总(持续更新)
前端