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

结尾

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

相关推荐
桂月二二38 分钟前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
沈梦研2 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
hunter2062062 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb2 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角2 小时前
CSS 颜色
前端·css
轻口味2 小时前
Vue.js 组件之间的通信模式
vue.js
浪浪山小白兔3 小时前
HTML5 新表单属性详解
前端·html·html5
lee5763 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579653 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter
limit for me4 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架