Vue之插槽

历史总是惊人的相似,知识总是学了忘、忘了学。
事情是这样的,我现在使用Vue开始着手做一个后台管理系统,正在我开开心心的照着视频“抄代码”的时候,项目中使用到v-slot指令使我很是懵*,明明学过的知识就是模糊不清。所以就来写一篇博客加深记忆。
在这里插入图片描述

一、为什么使用插槽

在生活中很多地方都有插槽,比如电脑的USB,插板的电源插座,不难理解插槽的目的就是让我们原来的设备具备扩展性。在Vue组件封装中,插槽更是必不可少的一个特性,它可以使我们的封装的组件更加的灵活。

二、插槽的基本使用

在这里插入图片描述
实现上面的效果时就可以使用插槽,我们发现组件最上面的内容是固定的,下面的是不一样的,所以我们可以在组件中这样定义。

<template>
  <section>
    <h3>固定内容</h3>
    <slot></slot>
  </section>
</template>

使用时只需要在组件标签中填写我们想要的信息,slot将会被自动替换掉

<template>
  <div id="app">
    <home>
      <button>按钮</button>
    </home>
    <home>
      <span>不固定内容</span>
    </home>
    <home>
      <h1>biaoti</h1>
    </home>
  </div>
</template>
<script>
import Home from "./components/Home.vue";
export default {
  components: { Home },
  name: "App"
};
</script>

三、具名插槽

当我们想要向组件中替换多个内容,这时候就可以使用具名插槽。
通俗理解,具名插槽就是给插槽起个名字,我们在使用时就可以替换指定的插槽。

具体使用:

<template>
  <section>
    <h3>固定内容</h3>
    <slot name="header"></slot>
    <slot name="body"></slot>
    <slot name="footer"></slot>
  </section>
</template>

我们可以通过以下方式进行替换

<template>
  <div id="app">
    <home>
      <h4 slot="header">header</h4>
      <h4 slot="body">body</h4>
      <h4 slot="footer">footer</h4>
    </home>
  </div>
</template>
<script>
import Home from "./components/Home.vue";
export default {
  components: { Home },
  name: "App"
};
</script>

四、作用域插槽

这个作用域比较难理解,在学懂它之前需要理解一个概念-编译作用域

1. 什么是编译作用域

首先,我们考虑下面Home组件是否可以在父组件中渲染出来

Home.vue

<template>
  <section>
    <h3>固定内容</h3>
    <slot name="header"></slot>
    <slot name="body"></slot>
    <slot name="footer"></slot>
  </section>
</template>

<script>
export default {
  data() {
    return {
      isShow: false
    };
  }
};
</script>

App.vue

<template>
  <div id="app">
    <home v-show="isShow">
      <h4 slot="header">header</h4>
      <h4 slot="body">body</h4>
    </home>
  </div>
</template>
<script>
import Home from "./components/Home.vue";
export default {
  data() {
    return {
      isShow: true
    };
  },
  components: { Home },
  name: "App"
};
</script>

结果是可以渲染出来的,官方给出的解释:“父组件所有的东西都会在父级作用域内编译,子组件所有的东西都会在子级作用域中编译”。
当我们在App.vue中使用Home.vue时,整个home组件的使用过程是相当于父组件出现的,所以home组件的作用域就是父组件,使用的属性也是父组件的属性。所以isShow使用的是App.vue实例中的属性,而不是子组件的属性。

2. 理解作用域插槽

作用域插槽就是父组件替换插槽的标签,内容有子组件来提供。

还是先来写一个案例:

子组件中包含一组数据,pLanguages:[‘javascript’,‘python’,‘Go’],在子组件中默认是列表的形式展示的,我想在父组件中以另一种方式展示这组数据

这时候可以通过在插槽上绑定一个属性拿到pLanguages的数据,为的是可以在父组件通过v-slot拿到子组件的数据,此时子组件中默认的以li的形式渲染

<template>
  <section>
    <ul>
      <slot :data="pLanguages">
        <li v-for="item in pLanguages">{{ item }}</li>
      </slot>
    </ul>
  </section>
</template>

<script>
export default {
  name: "",
  data() {
    return {
      pLanguages: ["javascript", "python", "Go"]
    };
  },
  methods: {}
};
</script>
<style lang="scss" scoped></style>

为了在父组件中以另外一种形式展示pLanguages中的数据,首先我们需要在父组件中定义一个template模板 ,添加v-slot属性,通过pLanguages.data拿到子组件中的数据重新展示

<template>
  <div id="app">
    <home>
      <template v-slot="pLanguages">
        <span v-for="item in pLanguages.data">{{ item }}-</span>
      </template>
    </home>
  </div>
</template>
<script>
import Home from "./components/Home.vue";
export default {
  data() {
    return {};
  },
  components: { Home },
  name: "App"
};
</script>

总结一下:作用域插槽的作用就是将子组件中的数据在父组件以另外一种方式展示出来,通过在子组件slot标签上定义的绑定属性来拿到此时子组件的数据,在父组件可以通过v-slot的指令拿到子组件的数据

五、补充说明

  1. 当标签内有内容时,在父组件展示不替换插槽时会以子组件标签内的默认内容作为展示
  2. 在使用作用域插槽时,在父组件获取子组件数据时,在vue2.5.x以下版本必须使用template模板,在vue2.5.x以上版本可以时其他标签
Vue 中,动态插槽(Dynamic Slots)允许开发者根据运行时的状态或数据动态地渲染插槽内容。Vue 3 提供了更加灵活的语法来实现动态插槽,主要通过 `v-slot` 指令结合动态插槽名称来实现。以下是一些关键点和示例代码,帮助理解如何在 Vue 中使用动态插槽。 ### 动态插槽的基本概念 动态插槽的核心在于使用 `v-slot:[dynamicSlotName]` 语法,其中 `dynamicSlotName` 是一个动态绑定的插槽名称。这种方式允许根据组件的状态或属性动态选择插槽内容。 ### 示例:Vue 3 中的动态插槽 #### 子组件:定义多个插槽 ```vue <!-- ChildComponent.vue --> <template> <div> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> </template> ``` #### 父组件:动态选择插槽 ```vue <!-- ParentComponent.vue --> <template> <child-component> <!-- 动态插槽 --> <template v-slot:[dynamicSlotName]> <p>这是动态插槽的内容!</p> </template> </child-component> </template> <script> export default { data() { return { dynamicSlotName: 'header' // 可以是 'header'、'default' 或 'footer' }; } }; </script> ``` 在这个示例中,`dynamicSlotName` 的值决定了哪个插槽会被渲染。如果 `dynamicSlotName` 的值为 `'header'`,则 `<p>这是动态插槽的内容!</p>` 会渲染在子组件的 `header` 插槽中。 ### 动态插槽与作用域插槽结合 动态插槽也可以与作用域插槽结合使用,允许子组件将数据传递给父组件的插槽内容。 #### 子组件:传递数据到插槽 ```vue <!-- ChildComponent.vue --> <template> <div> <slot name="custom" :user="user" :role="role"></slot> </div> </template> <script> export default { data() { return { user: { name: 'Alice', age: 25 }, role: 'admin' }; } }; </script> ``` #### 父组件:动态插槽与作用域插槽结合 ```vue <!-- ParentComponent.vue --> <template> <child-component> <template v-slot:[slotName]="{ user, role }"> <p>用户:{{ user.name }}, 角色:{{ role }}</p> </template> </child-component> </template> <script> export default { data() { return { slotName: 'custom' }; } }; </script> ``` 在这个示例中,`slotName` 的值决定了哪个插槽会被渲染,并且通过作用域插槽传递了 `user` 和 `role` 数据[^2]。 ### 总结 动态插槽Vue 中一种强大的功能,它允许根据运行时的状态或数据动态选择插槽内容。通过 `v-slot:[dynamicSlotName]` 语法,可以灵活地控制插槽的渲染方式,并结合作用域插槽传递数据,从而实现更加复杂的 UI 交互和组件复用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值