《Vue3 五》组件的插槽

插槽 Slot 可以让组件的使用者来决定组件中的某一块区域到底存放什么样的元素和内容。

使用插槽:

插槽的使用过程其实就是抽取共性、预留不同。将共同的元素、内容依然留在组件内进行封装;将不同的元素使用 slot 作为占位,让外部决定到底显示什么样的元素。

// App.vue
<template>
  <!-- 2. 在父组件中调用子组件时,子组件开始标签和结束标签之间的内容将会被插入到子组件的插槽中 -->
  <AppContent>
    <button>按钮</button>
  </AppContent>

  <AppContent>
    <a href="http:www.com">百度一下</a>
  </AppContent>
</template>

<script>
import AppContent from './components/AppContent'

export default {
  components: {
    AppContent,
  }
}
</script>

<style scoped>
</style>
// AppContent.vue
<template>
 <div>
  <h1>内容标题</h1>
  <!-- 1. 在子组件中预留插槽 -->
  <slot></slot>
 </div>
</template>

<script>
export default {
}
</script>

<style scoped>
</style>

在这里插入图片描述

插槽的默认内容:

<slot></slot>元素开始标签和结束标签之间的内容会作为插槽的默认内容,插槽的默认内容只会在没有提供插入的内容时显示。

// App.vue
<template>
  <!-- 2. 在父组件中调用子组件时,不提供插槽的内容 -->
  <AppContent />
</template>

<script>
import AppContent from './components/AppContent'

export default {
  components: {
    AppContent,
  }
}
</script>

<style scoped>
</style>
// AppContent.vue
<template>
 <div>
  <h1>内容标题</h1>
  <slot>
    <!-- 1. <slot></slot> 开始标签和结束标签之间的内容会作为插槽的默认内容显示 -->
    <div>这是插槽的默认内容</div>
  </slot>
 </div>
</template>

<script>
export default {
}
</script>

<style scoped>
</style>

在这里插入图片描述

具名插槽:

具名插槽:就是给插槽命名,通过 <slot> 元素的 name 属性可以给插槽命名。这样当一个组件中有多个插槽时,就可以区分出来要插入的内容是要插入哪个插槽中。

一个不带 name 的插槽,默认隐含的名字是 default。

// App.vue
<template>
  <NavBar>
    <!-- 2. 在父组件中,使用 template 元素包裹要插入到插槽中的内容,通过 v-slot:插槽的名称 来决定要插入哪个插槽中 -->
    <!-- v-slot:[变量名] 可以通过这种方式来动态地绑定插槽的名称 -->
    <!-- v-slot 的缩写为 # -->
    <template v-slot:left>
      <button>返回</button>
    </template>
    <template v-slot:center>
      <input />
    </template>
    <template v-slot:right>
      <button>搜索</button>
    </template>
  </NavBar>
</template>

<script>
import NavBar from './components/NavBar'

export default {
  components: {
    NavBar,
  }
}
</script>

<style scoped>
</style>
// NavBar.vue
<template>
 <div class='navbar'>
    <div class="left">
        <!-- 1. 在子组件中通过 name 属性给插槽命名 -->
        <slot name="left"></slot>
    </div>   
    <div class="center">
        <slot name="center"></slot>
    </div> 
    <div class="right">
        <slot name="right"></slot>
    </div> 
 </div>
</template>

<script>
export default {
}
</script>

<style scoped>
</style

作用域插槽:

作用域插槽的核心就是能够将子组件中的数据传递给父组件来使用。

// App.vue
<template>
  <AppContent>
    <!-- 2. 在父组件中,使用 template 元素包裹要插入到插槽中的内容,通过 v-slot:插槽名称="slotProps" 可以获取到子组件中指定插槽传递过来的数据 -->
    <template v-slot:default="slotProps">
      <p>{{ slotProps.content }}</p>
    </template>
  </AppContent>
</template>

<script>
import AppContent from './components/AppContent'

export default {
  components: {
    AppContent,
  }
}
</script>

<style scoped>
</style>
// AppContent.vue
<template>
 <div>
    <h1>子组件的标题</h1>
    <!-- 1. 在子组件中,通过给 slot 元素添加属性的方式给父组件传递数据 -->
    <slot content="子组件的内容"></slot>
 </div>
</template>

<script>
export default {
}
</script>

<style scoped>
</style>
### Vue3组件插槽的用法 在 Vue3 中,父组件可以通过 `<slot>` 元素向子组件传递内容。这种机制允许父组件定义子组件内部某些部分的具体表现形式,从而实现更灵活和可扩展的设计模式。 #### 默认插槽 默认插槽是最基本的形式,它不需要任何名称或额外配置即可工作。当子组件中存在未命名的 `<slot>` 时,父组件可以直接将 HTML 或其他组件作为其内容嵌套到该位置上。 ```html <!-- 子组件 Card.vue --> <template> <div class="card"> <h4>Card Title</h4> <slot></slot> <!-- 这里是默认插槽 --> </div> </template> <script> export default { name: &#39;Card&#39; } </script> ``` 父组件可以这样使用: ```html <Card> This is the content of the card. </Card> ``` 上述代码会将 “This is the content of the card.” 渲染到 `Card` 组件中的默认插槽处[^1]。 --- #### 命名插槽 为了支持更加复杂的布局需求,Vue 提供了 **命名插槽** 的功能。通过给 `<slot>` 添加名字属性 (`name`) 来区分不同的区域,并让父级能够针对这些特定的名字填充相应的内容。 以下是带有头部 (header) 和底部 (footer) 的卡片组件的例子: ```html <!-- 子组件 NamedSlotsExample.vue --> <template> <div class="container"> <header><slot name="header"></slot></header> <main><slot></slot></main> <!-- 默认插槽 --> <footer><slot name="footer">Default Footer Content</slot></footer> </div> </template> ``` 而在父组件中,则利用 `v-slot:` 指令绑定具体数据至对应的插槽之中: ```html <NamedSlotsExample> <template v-slot:header> <h2>This is a custom header.</h2> </template> <p>Main body text goes here...</p> <template v-slot:footer> <button type="button">Custom Button in Footer</button> </template> </NamedSlotsExample> ``` 这里分别设置了自定义头尾部以及主体部分内容;如果某个命名插槽没有被覆盖,默认显示设置好的备用文字【如 footer 部分】[^2]。 --- #### 作用域插槽 除了单纯传输静态结构外,有时还需要共享一些动态的数据或者方法给外部调用者——这便是所谓的作用域插槽所解决的问题所在。我们可以在 slot 上附加额外的信息并通过 props 形式暴露出去供使用者读取并处理后再呈现最终效果。 下面展示了一个列表项组件案例,其中每一行都接收来自父级传递过来的对象数组之一员作参数: ```html <!-- 子组件 ScopedSlotList.vue --> <template> <ul> <li v-for="(item, index) in items" :key="index"> <slot :text="item.text" :id="item.id"></slot> </li> </ul> </template> <script> export default { data() { return {items:[{ id:1 ,text:&#39;Item One&#39;},{ id:2,text:&#39;Item Two&#39;}]} } }; </script> ``` 接着,在实际运用场景下就可以像如下这般操作啦! ```html <ScopedSlotList> <template v-slot="{ text }"> {{ text }} </template> </ScopedSlotList> ``` 此片段表明我们将每条记录里的文本字段提取出来单独成列进行可视化输出。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值