Vue 中插槽(Slot)用法

Slow菜鸟 2024-08-18 11:33:01 阅读 84

Vue 中插槽(Slot)用法

(一)插槽用法概念(二)插槽的基本类型1. 默认插槽(Default Slot)2. 具名插槽(Named Slots)3. 作用域插槽(Scoped Slots)4. 动态插槽名(Dynamic Slot Names)5. 插槽后备内容(Slot Fallback Content)6. Vue 2.6.0之前与Vue 2.6.0后的比对6.1 默认插槽 缩写(由不写变成v-slot)6.2 具名插槽 缩写 (由slot变成 v-slot)6.3 作用域插槽 缩写 (由slot变成 v-slot)

(三)插槽中数据传递方式归纳

(一)插槽用法概念

在Vue中,子组件的模板可以定义多个插槽(包括默认插槽和具名插槽等等),

而父组件在引用子组件时,可以<code>根据需要 有选择性的为这些插槽插入内容。

如果父组件没有为某个插槽提供内容,那么子组件的模板中该插槽的位置将显示为该插槽的默认内容(如果有的话),或者简单地留空。

(二)插槽的基本类型

1. 默认插槽(Default Slot)

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

举例说明:

子组件 (DefaultSlotChild.vue)

<template>

<div class="child">code>

<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"> code>

<h2>我是子组件的标题</h2>

<!-- 这里的内容会被渲染到子组件的默认插槽中 -->

<p>这是来自父组件的默认插槽内容。111</p>

<p>这是来自父组件的默认插槽内容。222</p>

</div>

</template>

<!-- 以上内容是子组件中的内容 end-->

</div>

</template>

2. 具名插槽(Named Slots)

定义:带有名称的插槽,用于接收父组件中明确指定插槽名称的内容。用法:在子组件中使用<slot name="插槽名称"></slot>code>定义具名插槽,父组件中通过<template v-slot:插槽名称>或简写为<template #插槽名称>来指定内容应该插入哪个具名插槽。

举例说明:

子组件 (NamedSlotChild.vue)

<template>

<div class="child">code>

<header>

<!-- 具名插槽:header -->

<slot name="header"></slot> code>

</header>

<main>

<!-- 默认插槽 -->

<slot></slot>

</main>

<footer>

<!-- 具名插槽:footer -->

<slot name="footer"></slot> code>

</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">code>

<slot name="item" :item="item">code>

<!-- 后备内容 -->

{ { 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">code>

<!-- 使用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="动态名称"code>来绑定插槽的名称,其中动态名称可以是一个计算属性、方法返回值或数据属性。

举例说明:

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

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

父组件(简化示例)

<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>

5. 插槽后备内容(Slot Fallback Content)

定义:当父组件没有为插槽提供内容时,子组件可以定义一些后备内容作为默认显示。用法:在子组件的<slot>标签内部直接放置的内容,如果父组件没有为该插槽提供内容,则显示这些后备内容。

子组件 (SlotFallbackChild.vue)

<template>

<div>

<slot>

<!-- 后备内容:如果没有提供插槽内容,则显示这个 -->

<p>如果没有提供内容,将显示这段后备文本。</p>

</slot>

</div>

</template>

父组件

<template>

<div>

<!-- 提供了插槽内容,所以后备内容不会显示 -->

<SlotFallbackChild>

<p>这是来自父组件的插槽内容。</p>

</SlotFallbackChild>

<!-- 没有提供插槽内容,将显示后备内容 -->

<SlotFallbackChild></SlotFallbackChild>

</div>

</template>

<script>

import SlotFallbackChild from './SlotFallbackChild.vue';

export default {

components: {

SlotFallbackChild

}

}

</script>

6. Vue 2.6.0之前与Vue 2.6.0后的比对

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

6.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>

6.2 具名插槽 缩写 (由slot变成 v-slot)

父组件

<child-component>

<template slot="header"><h1>这是头部内容</h1></template>code>

<template slot="footer"><p>这是底部内容</p></template>code>

</child-component>

子组件

<template>

<slot name="header"></slot>code>

<slot name="footer"></slot>code>

</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>code>

<slot name="footer"></slot>code>

</template>

6.3 作用域插槽 缩写 (由slot变成 v-slot)

父组件

<child-component>

<template slot="item" slot-scope="slotProps">code>

<p>{ -- -->{ slotProps.text }}</p>

</template>

</child-component>

子组件

<template>

<slot name="item" :text="itemText"></slot>code>

</template>

缩写后变成

父组件

<child-component>

<template v-slot:item="slotProps">code>

<p>{ -- -->{ slotProps.text }}</p>

</template>

</child-component>

或简写

<child-component>

<template #item="slotProps">code>

<p>{ -- -->{ slotProps.text }}</p>

</template>

</child-component>

子组件不变

<template>

<slot name="item" :text="itemText"></slot>code>

</template>

(三)插槽中数据传递方式

通过 作用域插槽 实现

子组件中的插槽如何传递给父组件用

举例

<!-- 子组件中 将someFormObject这个对象作为form属性传递给插槽-->

<slot name="form" :form="someFormObject">...</slot>code>

<!-- 父组件中 使用 slot-scope 属性 来接收form属性 -->

<template slot="form" slot-scope="{ form }">code>

<!-- 2.6 版后缩写 语法为 v-slot:插槽名称="{ 属性名称}" -->

<template v-slot:form="{ form }"> </template> code>

归纳

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

通过默认插槽、具名插槽、作用域插槽、动态插槽名、插槽后备内容以及插槽的简写语法等用法,Vue.js提供了灵活且强大的组件化解决方案。这些用法不仅提高了组件的复用性和灵活性,还降低了组件之间的耦合度,使得Vue.js应用更加易于开发和维护。

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



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。