vue 中插槽(slot)用法

该文章已生成可运行项目,

一、插槽用法及概念

slot又名插槽,是Vue的内容分发机制,组件内部的模板引擎使用slot元素作为承载分发内容的出口。插槽slot是子组件的一个模板标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决定的。slot又分为默认插槽,具名插槽和作用域插槽等。

二、插槽的基本类型

1. 默认插槽(Default Slot)
  • 定义:没有指定名称的插槽,用于接收父组件传递的未明确指定插槽名称的内容。
  • 用法:在子组件中使用<slot></slot>定义默认插槽的位置,父组件中直接放在子组件标签内的内容会被渲染到该位置。

举例说明:
子组件 (DefaultSlotChild.vue)

<template>
  <div class="child">
    <h2>我是子组件的标题</h2>
     <!-- 默认插槽 -->
    <slot></slot>
  </div>
</template>

父组件

<template>
  <div>
    <DefaultSlotChild>
      <!-- 这里的内容会被渲染到子组件的默认插槽中 -->
      <p>这是来自父组件的默认插槽内容。111</p>
      <p>这是来自父组件的默认插槽内容。222</p>
    </DefaultSlotChild>
  </div>
</template>

<script>
import DefaultSlotChild from './DefaultSlotChild.vue';

export default {
  components: {
    DefaultSlotChild
  }
}
</script>

父组件上最终效果

<template>
 <div> 

 <!-- 以下内容是子组件中的内容 begin-->  
  <template>
   <div class="child">  
    <h2>我是子组件的标题</h2>  
    <!-- 这里的内容会被渲染到子组件的默认插槽中 -->  
    <p>这是来自父组件的默认插槽内容。111</p>
    <p>这是来自父组件的默认插槽内容。222</p>
   </div> 
  </template> 
  <!-- 以上内容是子组件中的内容 end--> 
 
 </div>
</template>
2. 具名插槽(Named Slots)
  • 定义:带有名称的插槽,用于接收父组件中明确指定插槽名称的内容。
  • 用法:在子组件中使用<slot name="插槽名称"></slot>定义具名插槽,父组件中通过<template v-slot:插槽名称>或简写为<template #插槽名称>来指定内容应该插入哪个具名插槽。

举例说明:
子组件 (NamedSlotChild.vue)

<template>
  <div class="child">
    <header>
     <!-- 具名插槽:header -->
      <slot name="header"></slot> 
    </header>
    <main>
    <!-- 默认插槽 -->
      <slot></slot> 
    </main>
    <footer>
    <!-- 具名插槽:footer -->
      <slot name="footer"></slot> 
    </footer>
  </div>
</template>

父组件

<template>
  <NamedSlotChild>
    <template v-slot:header>
      <!-- 这里的内容会被渲染到子组件的header插槽中 -->
      <h1>这是标题</h1>
    </template>
    <p>这是默认插槽的内容。</p>
    <template v-slot:footer>
      <!-- 这里的内容会被渲染到子组件的footer插槽中 -->
      <p>这是页脚</p>
    </template>
  </NamedSlotChild>
</template>

<script>
import NamedSlotChild from './NamedSlotChild.vue';

export default {
  components: {
    NamedSlotChild
  }
}
</script>
3. 作用域插槽(Scoped Slots)
  • 定义:一种特殊的插槽,允许子组件将数据暴露给父组件的插槽内容。
  • 用法
    在子组件中,通过
    <slot :数据名="数据值"></slot>将数据传递给插槽;
    在父组件中,通过
    <template v-slot:插槽名称="slotProps">接收数据,并使用slotProps来访问传递过来的数据。

举例说明
子组件 (ScopedSlotChild.vue)

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      <slot name="item" :item="item">
        <!-- 后备内容 -->
        {{ item.text }}
      </slot>
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, text: '苹果' },
        { id: 2, text: '香蕉' },
        { id: 3, text: '橙子' }
      ]
    }
  }
}
</script>

父组件

<template>
  <ScopedSlotChild>
    <template v-slot:item="slotProps">
      <!-- 使用slotProps访问子组件传递的数据 -->
      <strong>{{ slotProps.item.text }}</strong>
    </template>
  </ScopedSlotChild>
</template>

<script>
import ScopedSlotChild from './ScopedSlotChild.vue';

export default {
  components: {
    ScopedSlotChild
  }
}
</script>
4. 动态插槽名(Dynamic Slot Names)
  • 定义:允许插槽的名称是动态的,根据组件的状态或其他条件来决定使用哪个插槽。
  • 用法:在父组件中,通过:slot="动态名称"来绑定插槽的名称,其中动态名称可以是一个计算属性、方法返回值或数据属性。

举例说明:

这个例子稍微复杂一些,因为它通常用于更高级的场景,比如根据条件动态渲染不同的插槽。但基本思想是使用计算属性或方法来返回插槽名。

子组件(与前面的例子类似,不需要特别修改)

父组件(简化示例)

<template>  
  <div>  
    <NamedSlotChild>  
      <!-- 使用计算属性dynamicSlotName来决定内容应该渲染到哪个插槽中 -->  
      <template v-slot:[dynamicSlotName]>  
        <p>这是根据条件动态插入到对应插槽的内容。</p>  
      </template>  
    </NamedSlotChild>  
  </div>  
</template>  
  
<script>  
import NamedSlotChild from './NamedSlotChild.vue';  
  
export default {  
  components: {  
    NamedSlotChild  
  },  
  computed: {  
    // 假设这里根据某个条件返回不同的插槽名  
    dynamicSlotName() {  
      // 示例:根据某个数据属性来决定  
      const someCondition = true; // 实际应用中这里可能是更复杂的逻辑或响应式数据  
      if (someCondition) {  
        return 'header';  
      } else {  
        return 'footer';  
      }  
    }  
  }  
}  
</script>

三、Vue 2.6.0之前与Vue 2.6.0后的比对

在Vue 2.6.0及以后的版本中,Vue团队对插槽(slot)的语法进行了简化和改进,引入了v-slot指令来替代原有的slot和slot-scope语法

1.默认插槽 缩写(由不写变成v-slot)
父组件
<child-component><p>这是默认插槽的内容</p></child-component>

子组件
<template><slot></slot></template>

缩写后变成

父组件(推荐使用<template>标签,但也可直接用于元素上)
<child-component>
<template v-slot><p>这是默认插槽的内容</p></template>
</child-component>

或(注意:直接在元素上使用v-slot较少见,且可能需要额外配置)
<child-component>
<p v-slot></p>
</child-component>


子组件不变
<template><slot></slot></template>
2.具名插槽 缩写 (由slot变成 v-slot)
父组件
<child-component>
<template slot="header"><h1>这是头部内容</h1></template>
<template slot="footer"><p>这是底部内容</p></template>
</child-component>

子组件
<template>
<slot name="header"></slot>
<slot name="footer"></slot>
</template>

缩写后变成

父组件
<child-component>
<template v-slot:header><h1>这是头部内容</h1></template>
<template v-slot:footer><p>这是底部内容</p></template>
</child-component>

或简写
<child-component>
<template #header><h1>这是头部内容</h1></template>
<template #footer><p>这是底部内容</p></template>
</child-component>

子组件不变
<template>
<slot name="header"></slot>
<slot name="footer"></slot>
</template>
3.作用域插槽 缩写 (由slot变成 v-slot)
父组件
<child-component>
<template slot="item" slot-scope="slotProps">
<p>{{ slotProps.text }}</p>
</template>
</child-component>

子组件
<template>
<slot name="item" :text="itemText"></slot>
</template>

缩写后变成

父组件
<child-component>
<template v-slot:item="slotProps">
<p>{{ slotProps.text }}</p>
</template>
</child-component>

或简写
<child-component>
<template #item="slotProps">
<p>{{ slotProps.text }}</p>
</template>
</child-component>

子组件不变
<template>
<slot name="item" :text="itemText"></slot>
</template>

结语:

插槽是Vue.js中非常重要的一个概念,它允许父组件向子组件的模板中插入内容,从而实现组件内容的分发和组合。

1.复用组件:插槽可以使组件更加灵活和可复用,使用者可以根据需要在插槽中插入不同的内容,而不需要修改组件的源代码。

2.定制化(组件可扩展性):插槽可以用来定制组件的外观和功能。通过插槽,使用者可以自定义组件中特定的部分,从而满足自己的需求。

3.组件通信:插槽也可以用于组件之间的通信。通过插槽,父组件可以向子组件传递数据或者方法,子组件可以通过插槽接收并使用这些数据或方法。

在实际开发中,根据具体的需求和场景选择合适的插槽用法,可以构建出高效、可维护的Vue.js应用。

本文章已经生成可运行项目
### 如何在 Ant Design Vue 中使用组件插槽 Ant Design Vue 是一个基于 Vue 的高质量 UI 组件库,提供了丰富的组件支持。通过插槽Slot),开发者可以灵活地自定义组件内部的内容结构和样式。 #### 插槽的基础概念 Vue 提供了三种类型的插槽:默认插槽、具名插槽和作用域插槽。这些插槽机制同样适用于 Ant Design Vue 的各个组件中[^2]。 --- #### 默认插槽 (Default Slot) 默认插槽是最简单的形式,用于向组件传递内容。以下是 `a-button` 组件的一个简单例子: ```vue <template> <a-button> 点击按钮 </a-button> </template> ``` 在这个例子中,“点击按钮”作为默认插槽被传入到 `a-button` 组件中。 --- #### 具名插槽 (Named Slot) 当需要在一个组件的不同位置插入多个内容时,可以使用具名插槽。例如,在表格 (`a-table`) 组件中,可以通过具名插槽来自定义表头或操作列的内容。 以下是一个使用 `a-table` 和具名插槽的例子: ```vue <template> <a-table :columns="columns" :data-source="dataSource"> <!-- 自定义表头 --> <template #headerCell="{ column }"> <span v-if="column.key === 'name'" style="color: blue;"> {{ column.title }} </span> </template> <!-- 自定义单元格内容 --> <template #bodyCell="{ column, record }"> <div v-if="column.key === 'action'"> 编辑 | 删除 </div> </template> </a-table> </template> <script lang="ts" setup> import { ref } from 'vue'; const columns = [ { title: '姓名', dataIndex: 'name', key: 'name' }, { title: '年龄', dataIndex: 'age', key: 'age' }, { title: '操作', key: 'action' } ]; const dataSource = ref([ { name: '张三', age: 28, key: '1' }, { name: '李四', age: 30, key: '2' } ]); </script> ``` 上述代码展示了如何利用具名插槽 `#headerCell` 和 `#bodyCell` 来分别修改表头和单元格中的内容[^1]。 --- #### 作用域插槽 (Scoped Slot) 作用域插槽允许父组件访问子组件的数据并对其进行处理。这通常用于动态生成列表项或其他复杂场景。 下面是一个关于 `a-select` 组件的作用域插槽示例: ```vue <template> <a-select v-model:value="value" style="width: 120px"> <template #dropdownRender="{ menuNode }"> <ul class="custom-dropdown-menu"> <li v-for="(item, index) in options" :key="index">{{ item.label }}</li> </ul> </template> </a-select> </template> <script lang="ts" setup> import { ref } from 'vue'; const value = ref(''); const options = [ { label: '选项一', value: 'option1' }, { label: '选项二', value: 'option2' } ]; </script> ``` 在此示例中,`#dropdownRender` 被用来完全替换下拉菜单的默认渲染逻辑,并提供了一个更自定义的布局。 --- #### 实际应用场景 以级联选择器 (`cascader`) 为例,其内部实现了复杂的嵌套数据展示功能。如果想要进一步增强用户体验,则可通过插槽实现个性化设计。比如,可以在选中某一项后显示额外的信息面板[^3]。 ```vue <template> <a-cascader v-model:value="selectedValue" :options="options" expand-trigger="hover" > <template #suffixIcon> <icon-custom /> </template> </a-cascader> </template> <script lang="ts" setup> import IconCustom from './components/IconCustom.vue'; import { ref } from 'vue'; const selectedValue = ref([]); const options = [ { value: 'zhejiang', label: '浙江', children: [ { value: 'hangzhou', label: '杭州' } ] } ]; </script> ``` 此案例说明了如何借助 `#suffixIcon` 替换默认图标,从而提升界面美观度。 --- #### 总结 以上介绍了 Ant Design Vue插槽的主要用法及其实际应用方式。无论是基础的按钮还是高级的功能型组件,都可以通过合理运用插槽达到更高的定制化水平。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值