vue3中Slot常见使用

Posted 嘴巴嘟嘟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3中Slot常见使用相关的知识,希望对你有一定的参考价值。

下面先来认识一下插槽

在开发中,我们会经常封装一个个可复用的组件:

  1. 前面我们会通过props传递给组件一些数据,让组件来进行展示;
  2. 但是为了让这个组件具备更强的通用性,我们不能将组件中的内容限制为固定的div、span等等这些元素;
  3. 我们应该让使用者可以决定某一块区域到底存放什么内容和元素;

如何使用插槽slot?

  1. 插槽的使用过程其实是抽取共性、预留不同
  2. 我们会将共同的元素、内容依然在组件内进行封装;
  3. 同时会将不同的元素使用slot作为占位,让外部决定到底显示什么样的元素;
  4. 在封装组件中,使用特殊的元素就可以为封装组件开启一个插槽;
  5. 该插槽插入什么内容取决于父组件如何使用;

插槽的基本使用


App.vue

<template>
  <div>
    <my-slot-cpn>
      <button>我是按钮</button>
    </my-slot-cpn>
    <my-slot-cpn>
      <my-input-cpn />
    </my-slot-cpn>
    <h2>我不是插槽的组件</h2>
    <my-slot-cpn>
      <h4>插槽里面很多内容</h4>
      <i>你信不信我</i>
      <del>啦啦啦啦啦</del>
    </my-slot-cpn>
    <my-slot-cpn></my-slot-cpn>
  </div>
</template>

<script>
import MySlotCpn from "./MySlotCpn.vue";
import MyInputCpn from "./MyInputCpn.vue";
export default {
  name: "App",
  components: { MySlotCpn, MyInputCpn },
  methods: {},
};
</script>

<style scoped>
</style>

MySlotCpn.vue

<template>
  <div>
    <h3>组件的开始</h3>
    <slot>
      <i>我是插槽,没有填写信息,我就是默认的</i>
    </slot>
    <h3>组件的结束</h3>
  </div>
</template>

<script>
export default {};
</script>

<style lang="scss" scoped>
</style>

MyInputCpn.vue

<template>
  <div>
    <input type="text" placeholder="我是输入框" />
  </div>
</template>

<script>
export default {};
</script>

<style lang="scss" scoped>
</style>

具名插槽的使用-动态插槽名

  1. 具名插槽顾名思义就是给插槽起一个名字, 元素有一个特殊的 attribute:name;
  2. 一个不带 name 的slot,会带有隐含的名字 default;

我们可以通过 v-slot:[dynamicSlotName]方式动态绑定一个名称;
具名插槽使用的时候缩写:
跟 v-on 和 v-bind 一样,v-slot 也有缩写;
即把参数之前的所有内容 (v-slot:) 替换为字符 #;

<template>
  <div>
    <nar-bar :name="name">
      <template v-slot:left> 我是左边的插槽 </template>
      <template v-slot:center>我是中间的插槽</template>
      <template v-slot:right>我是右边的插槽</template>
      <template #[name]>我是语法糖和动态插槽</template>
    </nar-bar>
  </div>
</template>

<script>
import NarBar from "./NarBar.vue";

export default {
  name: "App",
  data() {
    return {
      name: "lisi",
    };
  },
  components: {
    NarBar,
  },
};
</script>

<template>
  <div>
    <div class="nav-bar">
      <div class="left"><slot name="left"></slot></div>
      <div class="center"><slot name="center"></slot></div>
      <div class="right"><slot name="right"></slot></div>
      <div class="name"><slot :name="name"></slot></div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    name: String,
  },
};
</script>

渲染作用域

在Vue中有渲染作用域的概念:

  1. 父级模板里的所有内容都是在父级作用域中编译的;
  2. 子模板里的所有内容都是在子作用域中编译的;

案列

认识作用域插槽

但是有时候我们希望插槽可以访问到子组件中的内容是非常重要的:

  1. 当一个组件被用来渲染一个数组元素时,我们使用插槽,并且希望插槽中没有显示每项的内容;
  2. 这个Vue给我们提供了作用域插槽;

使用步骤

ShowNames.vue

<template>
  <div>
    <template v-for="(item, index) in names" :key="item">
      <slot :item="item" :index="index"></slot>
      <slot name="lisi"></slot>
    </template>
  </div>
</template>

<script>
  export default {
    props: {
      names: {
        type: Array,
        default: () => []
      }
    }
  }
</script>

<style scoped>

</style>

App.vue

<template>
  <div>
    <nar-bar :name="name">
      <template v-slot:left> 我是左边的插槽 </template>
      <template v-slot:center>我是中间的插槽</template>
      <template v-slot:right>我是右边的插槽</template>
      <template #[name]>我是语法糖和动态插槽</template>
    </nar-bar>
    <hr />
    <show-names :names="names">
      <template v-slot="names">
        <p>{{ names.item }}-{{ names.index }}</p>
      </template>
    </show-names>
    <hr />
    // 如果我们有默认插槽和具名插槽,那么按照完整的template来编写
    <show-names :names="names">
      <template v-slot="slotProps">
        <span>{{ slotProps.item }}---{{ slotProps.index }}</span>
      </template>
    </show-names>
    <hr />
    // 果我们的插槽只有默认插槽时,组件的标签可以被当做插槽的模板来使用,这样,我们就可以将 v-slot 直 接用在组件上
    <show-names :names="names" v-slot="slotProps">
      <button>{{ slotProps.item }}-{{ slotProps.index }}</button>
    </show-names>
    <hr />
    <show-names :names="names">
      <template v-slot="slotProps">
        <button>{{ slotProps.item }}-{{ slotProps.index }}</button>
      </template>
      //如果我们的插槽是默认插槽default,那么在使用的时候 v-slot:default="slotProps"可以简写为vslot="slotProps":
      <template v-slot:lisi>
        <h2>我是name的插入内容</h2>
      </template>
    </show-names>
  </div>
</template>

<script>
import NarBar from "./NarBar.vue";
import ShowNames from "./ShowNames.vue";

export default {
  name: "App",
  data() {
    return {
      names: ["张三", "李四", "王五", "赵六", "孙七"],
    };
  },
  components: {
    NarBar,
    ShowNames,
  },
};
</script>

以上是关于vue3中Slot常见使用的主要内容,如果未能解决你的问题,请参考以下文章

vue3基础练习

(十八)补充-Vue3中插槽的使用

vue3 | slots

vue2升级vue3:Vue2/3插槽——vue3的jsx组件插槽slot怎么处理

Vue3 插槽使用详解

[vue3进阶] 4.slot插槽1——基本用法和默认值