Vue~插槽

什么是插槽

插槽:英文单词 slot

抽取公共组件时,组件内部总会出现一些差异性内容;Vue中提供了一种空间占位语法,称为插槽

1,匿名插槽

项目视图中,子组件中占有一个差异位置,可以通过匿名插槽实现占位

列表页面中,需要展示不同类型数据的新闻数据、通知数据、公告数据

① 定义插槽:src/components/DataList.vue

<template>
  <div class="s-container">
    <h3>功能组件</h3>
    <div>
      <!-- 插槽:匿名插槽 -->
      <slot></slot>
    </div>
    <div>
      公共底部内容
    </div>
  </div>
</template>

<script>
export default {

}
</script>

<style scoped>
.s-container{
  width: 400px;
  padding: 10px;
  border-radius: 5px;
  box-shadow: #333 0 0 2px;
}
</style>

② 给插槽中注入数据,编辑src/pages/List.vue

<template>
  <div class="list-container">
    <h2>列表页面</h2>
    <!-- 1、没有插入内容的子组件-->
    <DataList/>
    <!-- 2、新闻数据-->
    <DataList>
      <!-- 给匿名插槽添加内容 -->
      <ul>
        <li v-for="news in newsList" :key="news.id">{{ news.content}} </li>
      </ul>
    </DataList>
    <!-- 3、通知内容 -->
    <DataList>
      <ol>
        <li v-for="notice in noticeList" :key="notice.id">{{notice.content}}</li>
      </ol>
    </DataList>
    <!-- 4、通知内容-->
    <DataList>
      <div v-for="advice in adviceList" :key="advice.id">{{advice.body}}</div>
    </DataList>
  </div>
</template>

<script>
import DataList from '../components/DataList.vue'

export default {
  data() {
    return {
      newsList: [
        {id: 2, content: "苹果系统升级"},
        {id: 1, content: "全球互联网大会"}
      ],
      noticeList: [
        {id: 1, content: "周末一起去玩!"}
      ],
      adviceList: [
        {id: 3, body: "周一上班"},
        {id: 2, body: "周二也要上班"},
        {id: 1, body: "周三还要上班!!!"}
      ]
    }
  },
  components: {
    DataList
  }
}
</script>

<style>

</style>

2,具名插槽

项目中定义弹出窗口,多个页面中都出现了弹窗,需要将弹窗抽取成一个功能组件;功能组件中不同的位置展示的内容不同,表示差异内容的位置不止一个!

① 定义包含具名插槽的公共组件:src/components/Dialog.vue

<template>
  <div class="d-container">
    <!-- 弹窗标题-->
    <h3><slot name="title"></slot></h3>
    <!-- 弹窗内容-->
    <p><slot></slot></p>
    <!-- 弹窗操作-->
    <div><slot name="opera"></slot></div>
  </div>
</template>

<script>
export default {

}
</script>

<style>
.d-container{
  width: 300px;
  height: 100px;
  box-shadow: #000 0 0 2px;
}
</style>

② 编辑src/pages/List.vue,添加具名插槽内容

<template>
  <div class="list-container">
    <!-- 具名插槽-->
    <Dialog>
      <template v-slot:title>
        警告信息对话框
      </template>
      <template v-slot:opera>
        <button>确认</button>
      </template>
      <p>
        警告信息的提示内容
      </p>
    </Dialog>
    <Dialog>
      <template #title>
        确认信息
      </template>
      <template #opera>
        <button>编辑</button>
        <button>确认</button>
      </template>
      <p>
        确认信息的提示内容
      </p>
    </Dialog>
    <Dialog>
      <template slot-scope:title>
        危险操作提示
      </template>
      <template slot-scope:opera>
        <button>确认操作</button>
      </template>
      <p>
        微信操作信息的提示内容
      </p>
    </Dialog>

  </div>
</template>

<script>
import DataList from '../components/DataList.vue'
import Dialog from '../components/Dialog.vue'

export default {
  data() {
    return {...},
  components: {
    DataList,
    Dialog
  }
}
</script>

<style>

</style>

3,作用域插槽

插槽中可以实现父组件给子组件注入数据完成数据的渲染;一旦输入的数据包含和用户之间的交互操作,需要子组件通过插槽给父组件传递数据

① 编写作用域插槽:src/components/ScopeList.vue

<template>
  <div class="sc-container">
    <ul>
      <li v-for="news in newsList" :key="news.id">
        <p>
          <span>{{ news.id }}</span>
          <span>{{ news.content }}</span>
          <span>
            <!-- 需要插槽给父组件传递正在操作的数据 -->
            <!-- 通过插槽的属性进行传递:作用域插槽-->
            <slot :row="news"></slot>
          </span>
        </p>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  props: ['newsList']
}
</script>

<style scoped>
.sc-container{
  padding:20px;
  box-shadow: #000 0 0 2px;
  width: 400px;
}
</style>

② 编辑src/pages/List.vue,添加接受作用域数据的插槽组件

<!-- 作用域插槽-->
<ScopeList :newsList="newsList">
    <template v-slot="props">
<button @click="checkDetail(props)">查看详情</button>
    </template>
</ScopeList>
<ScopeList :newsList="newsList">
    <template v-slot="attr">
<!-- <template slot-scope="attr"> -->
<button @click="edit(attr)">编辑</button>
<button @click="del(attr)">删除</button>
    </template>
</ScopeList>

插槽slot主要区分三种

  • 匿名插槽:
    • <slot></slot>
    • 功能组件中,添加唯一一个占位位置,由父组件指定这个位置的内容
  • 具名插槽:
    • <slot name="mySlot"></slot>
    • 功能组件中,需要在多个位置添加不同的内容,通过具名插槽实现,父组件中指定插槽的名称填充数据
  • 作用域插槽:
    • <slot :row="数据"></slot>
    • 功能组件中,需要将插槽中的数据传递给父组件使用;通过插槽的自定义属性进行数据传输
<think> 首先,用户要求了解Vue插槽的介绍、使用方法和相关特性。我需要基于提供的引用内容来构建回答。引用来自站内资料,我需要自然地引用它们。 关键点从引用中提取: - 引用[1]: Vue插槽是内容分发机制,允许组件模板部分由使用者自定义,用于灵活性和复用性。基本使用包括引言和基本使用。 - 引用[2]: 强调插槽增强组件复用性,通过预留位置动态插入内容。讨论了类型、用法和实际应用。 - 引用[3]: 提到作用域插槽、API特性如v-bind slot和slot-scope。还列出了学习资源。 - 引用[4]: 区分Props和插槽,Props用于传递数据,插槽用于内容分发。 用户查询:"我想了解Vue插槽的相关信息 请问Vue插槽的介绍、使用方法和相关特性"。所以,我需要覆盖: 1. 介绍:什么是Vue插槽,核心思想。 2. 使用方法:如何基本使用插槽。 3. 相关特性:包括作用域插槽、类型等。 系统指令: - 使用中文回答。 - 结构清晰,逐步解决问题。 - 在引用的段落末尾自然地添加引用标识,如[^1]。 - 生成相关问题。 - 确保LaTeX语法正确(尽管用户查询中没有数学内容,但如果有,需处理)。 - 回答结束时添加相关问题。 结构回答: 1. **介绍**:解释Vue插槽的概念,核心思想。 2. **使用方法**:详述基本使用、具名插槽等。 3. **相关特性**:覆盖作用域插槽、高级用法。 4. **应用场景**:讨论典型应用。 5. **相关问题**:在末尾生成相关问题。 自然地引用来源: - 当使用引用内容时,在句子末尾添加[^1], [^2], etc. - 例如:"Vue插槽是一种强大的内容分发机制,允许开发者创建灵活、可复用的组件[^1]。" 确保真实可靠:基于提供的引用,不要添加外部知识。 生成相关问题: - 在结尾添加类似示例的格式:"§§相关问题§§" 后列出问题。 - 例如:关于插槽的优化、应用场景等。 最终输出: - 以用户可见层开始。 - 结构化回答。 - 结束时添加相关问题。 </think>### Vue插槽的介绍、使用方法和相关特性 在Vue.js框架中,插槽(Slot)是一种核心特性,用于实现组件的灵活内容分发。它允许父组件向子组件注入自定义内容,从而提升组件的复用性和可定制性。以下我将逐步介绍Vue插槽的核心概念、基本使用方法、相关特性以及应用场景,确保内容基于可靠引用并结构清晰。 #### 1. **Vue插槽的介绍** Vue插槽是组件化开发中的内容分发机制,其核心思想是将组件的模板部分交由使用者自定义,实现结构和内容的动态组合[^1]。简单来说,插槽在子组件中预留“占位符”,父组件可以将任意内容(如HTML、文本或其他组件)插入这些位置。这使得组件能适应不同场景,而无需修改其内部逻辑。例如,一个按钮组件可以预留插槽,让父组件自定义按钮文本或图标,从而避免硬编码限制[^2]。Vue插槽通过增强组件复用性,提高了代码的可维护性和扩展性[^3]。 #### 2. **Vue插槽的使用方法** 使用Vue插槽涉及几个基本步骤,我将从简单到复杂逐步说明。确保在Vue组件中正确声明和使用插槽语法。 - **基本插槽(默认插槽)**: 在子组件的模板中,使用`<slot>`标签定义一个默认位置。父组件在引用子组件时,直接在标签内提供内容。例如: ```vue <!-- 子组件 ChildComponent.vue --> <template> <div> <slot></slot> <!-- 默认插槽位置 --> </div> </template> <!-- 父组件中使用 --> <ChildComponent> 这里是父组件插入的内容 <!-- 内容自动填充到slot位置 --> </ChildComponent> ``` 这种方法适用于简单的内容分发,父组件的内容会完全替换子组件的`<slot>`标签[^1][^2]。 - **具名插槽**: 当组件需要多个插槽位置时,使用具名插槽。子组件中为每个插槽指定`name`属性,父组件通过`v-slot`指令(或旧版的`slot`属性)指定目标插槽。例如: ```vue <!-- 子组件 LayoutComponent.vue --> <template> <div> <slot name="header"></slot> <!-- 具名插槽 --> <slot name="content"></slot> </div> </template> <!-- 父组件中使用 --> <LayoutComponent> <template v-slot:header> <h1>自定义标题</h1> <!-- 插入到header插槽 --> </template> <template v-slot:content> <p>这里是主要内容</p> <!-- 插入到content插槽 --> </template> </LayoutComponent> ``` 具名插槽提高了组件的灵活性,允许父组件精确控制内容分布[^2][^3]。 - **作用域插槽**: 作用域插槽允许子组件向父组件传递数据,实现双向通信。子组件在`<slot>`上使用`v-bind`绑定数据,父组件通过`v-slot`接收。例如: ```vue <!-- 子组件 ListComponent.vue --> <template> <ul> <li v-for="item in items" :key="item.id"> <slot :item="item"></slot> <!-- 绑定数据到插槽 --> </li> </ul> </template> <!-- 父组件中使用 --> <ListComponent :items="items"> <template v-slot:default="slotProps"> <span>{{ slotProps.item.name }}</span> <!-- 访问子组件传递的数据 --> </template> </ListComponent> ``` 作用域插槽常用于列表渲染或数据驱动型组件,提供更强大的定制能力[^3][^4]。 #### 3. **相关特性** Vue插槽支持多种高级特性,提升开发体验: - **默认内容**:在子组件的`<slot>`标签内定义默认内容,如果父组件未提供内容,则显示默认值。例如: ```vue <slot>默认文本</slot> <!-- 父组件不提供内容时显示"默认文本" --> ``` 这增强了组件的健壮性[^1][^2]。 - **动态插槽名**:使用动态绑定的插槽名,实现更灵活的模板逻辑。例如: ```vue <template v-slot:[dynamicSlotName]> 动态内容 </template> ``` 适用于需要根据状态变化的场景[^3]。 - **插槽与Props的区别**:Props用于父组件向子组件传递数据(如字符串、数组),而插槽用于传递内容(如HTML结构)。两者结合能覆盖完整组件通信需求:Props传递数据,插槽分发模板[^4]。 - **API特性**:Vue 2.x中,旧版语法如`slot="name"`或`slot-scope`仍被支持,但在Vue 3.x中推荐使用`v-slot`指令以确保代码清晰[^3]。 #### 4. **应用场景** Vue插槽适用于多种实际场景: - **UI组件库**:如按钮、卡片或布局组件,允许用户自定义内容而不修改源码[^1][^2]。 - **数据列表渲染**:结合作用域插槽,实现动态数据展示(如表格行定制),增强复用性[^3]。 - **复杂表单**:父组件注入表单字段或验证逻辑,保持组件独立性[^4]。 - **主题和风格定制**:通过插槽插入样式或主题相关元素,支持多主题切换[^2]。 总之,Vue插槽是提升组件灵活性的利器,通过合理使用,能显著减少代码冗余并加速开发。更多学习资源可参考Vue官方文档或Vue Mastery教程[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值