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快速绑定属性名,属性值,不过不用展开)

结尾

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

相关推荐
m0_7482552620 分钟前
easyExcel导出大数据量EXCEL文件,前端实现进度条或者遮罩层
前端·excel
web147862107231 小时前
C# .Net Web 路由相关配置
前端·c#·.net
m0_748247801 小时前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
飞的肖1 小时前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
青灯文案11 小时前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
m0_748254881 小时前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl
ZJ_.1 小时前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
GIS开发特训营1 小时前
Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍
前端·vue.js·前端框架·gis开发·webgis·三维gis
Cachel wood2 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
学代码的小前端2 小时前
0基础学前端-----CSS DAY9
前端·css