Vue—插槽

本文详细介绍了Vue中的插槽概念及其三种类型:默认插槽、具名插槽和作用域插槽。通过实例展示了如何在父组件和子组件之间传递结构和数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

## 插槽

1. 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 <strong style="color:red">父组件 ===> 子组件</strong> 。

2. 分类:默认插槽、具名插槽、作用域插槽

3. 使用方式:

1. 默认插槽:

```vue

父组件中:

<Category>

<div>html结构1</div>

</Category>

子组件中:

<template>

<div>

<!-- 定义插槽 -->

<slot>插槽默认内容...</slot>

</div>

</template>

```

2. 具名插槽:

```vue

父组件中:

<Category>

<templateslot="center">

<div>html结构1</div>

</template>

<templatev-slot:footer>

<div>html结构2</div>

</template>

</Category>

子组件中:

<template>

<div>

<!-- 定义插槽 -->

<slot name="center">插槽默认内容...</slot>

<slot name="footer">插槽默认内容...</slot>

</div>

</template>

```

3. 作用域插槽:

1. 理解:<span style="color:red">数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。</span>(games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)

2. 具体编码:

```vue

父组件中:

<Category>

<templatescope="scopeData">

<!-- 生成的是ul列表 -->

<ul>

<li v-for="g in scopeData.games":key="g">{{g}}</li>

</ul>

</template>

</Category>

<Category>

<templateslot-scope="scopeData">

<!-- 生成的是h4标题 -->

<h4v-for="g in scopeData.games" :key="g">{{g}}</h4>

</template>

</Category>

子组件中:

<template>

<div>

<slot :games="games"></slot>

</div>

</template>

<script>

exportdefault {

name:'Category',

props:['title'],

//数据在子组件自身

data() {

return {

games:['红色警戒','穿越火线','劲舞团','超级玛丽']

}

},

}

</script>

```

```

```

默认插槽



Category.vue:


<template>
    <div class="category">
        <h3>{{ title }}分类</h3>
        <!-- <ul>
            <li v-for="(item,index) in listData" :key="index">{{ item }}</li>
        </ul> -->
        <!--slot:定义一个插槽-->
        <!--组件标签的插槽放在这里-->
        <slot>我是一些默认值,当使用者没有传递具体结构时,我会出现</slot>
    </div>
</template>
<script>
export default {
    name:'C-category',
    props:['title']
}
</script>
<style>
    .category{
        background-color: pink;
        width: 200px;
        height: 300px;
    }
    h3{
        text-align: center;
        background-color: yellow;    
    }
    image{
        width: 100%;
        height: auto;
    }
</style>
App.vue:


<template>
    <div class="container">
        <category title="美食" >
            <img src="https://img1.baidu.com/it/u=3282457405,235959913&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=500" alt="">
        </category>
        <category title="游戏" :listData="games">
            <ul>
                <li v-for="(item,index) in games" :key="index">{{ item }}</li>
            </ul>
        </category>
        <category title="电影" :listData="films">
            <!--control:表示是否可以播放-->
            <video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
        </category>
    </div>
</template>
<script>
    import category from './components/Category.vue'
    export default {
        name:'App',
        components:{category},
        data(){
            return{
                foods:['火锅','烧烤','小龙虾','牛排'],
                games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
                films:['《教父》','《拆弹专家》','《你好,李焕英》','《尚硅谷》']
            }
        }
    }
</script>
<style scoped>
    .container{
        display: flex;
        justify-content: space-around;
        
    }
    img{
        width: 100%;
    }
    
    video{
        width: 100%;
    }

具名插槽

Category.vue:


<template>
    <div class="category">
        <h3>{{ title }}分类</h3>
        <!-- <ul>
            <li v-for="(item,index) in listData" :key="index">{{ item }}</li>
        </ul> -->
        <!--slot:定义一个插槽-->
        <!--组件标签的插槽放在这里-->
        <slot name="center"></slot>
        <slot name="footer"></slot>
    </div>
</template>
<script>
export default {
    name:'C-category',
    props:['title']
}
</script>
<style>
    .category{
        background-color: pink;
        width: 200px;
        height: 300px;
    }
    h3{
        text-align: center;
        background-color: yellow;    
    }
    image{
        width: 100%;
        height: auto;
    }
</style>
Category.vue:


<template>
    <div class="category">
        <h3>{{ title }}分类</h3>
        <!-- <ul>
            <li v-for="(item,index) in listData" :key="index">{{ item }}</li>
        </ul> -->
        <!--slot:定义一个插槽-->
        <!--组件标签的插槽放在这里-->
        <slot name="center"></slot>
        <slot name="footer"></slot>
    </div>
</template>
<script>
export default {
    name:'C-category',
    props:['title']
}
</script>
<style>
    .category{
        background-color: pink;
        width: 200px;
        height: 300px;
    }
    h3{
        text-align: center;
        background-color: yellow;    
    }
    image{
        width: 100%;
        height: auto;
    }
</style>

作用域插槽

Category.vue:


<template>
    <div class="category">
        <h3>{{title}}分类</h3>
        <!--通过slot传递参数games数组-->
        <slot :games="games" msg="hello">我是默认的一些内容</slot>
    </div>
</template>
<script>
    export default {
        name:'Category',
        props:['title'],
        data() {
            return {
                games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
            }
        },
    }
</script>
<style scoped>
    .category{
        background-color: pink;
        width: 200px;
        height: 300px;
    }
    h3{
        text-align: center;
        background-color: yellow;
    }
    video{
        width: 100%;
    }
    img{
        width: 100%;
    }
</style>
App.vue:


<template>
    <div class="container">
        <Category title="游戏">
            <!--这里的scope=“”可以随意写名字-->
            <template scope="Gui">
                <ul>
                    <li v-for="(g,index) in Gui.games" :key="index">{{g}}</li>
                </ul>
            </template>
        </Category>
        <Category title="游戏">
            <template scope="{games}">
                <ol>
                    <li style="color:red" v-for="(g,index) in games" :key="index">{{g}}</li>
                </ol>
            </template>
        </Category>
        <Category title="游戏">
            <template slot-scope="{games}">
                <h4 v-for="(g,index) in games" :key="index">{{g}}</h4>
            </template>
        </Category>
    </div>
</template>
<script>
    import Category from './components/Category'
    export default {
        name:'App',
        components:{Category},
    }
</script>
<style scoped>
    .container,.foot{
        display: flex;
        justify-content: space-around;
    }
    h4{
        text-align: center;
    }
</style>

### Vue 插槽的基础概念 Vue 中的插槽(Slot)是一种强大的功能,用于实现父组件向子组件传递内容的功能。它增强了组件设计的灵活性和可扩展性[^2]。 #### 默认插槽 默认插槽是最简单的形式,允许父组件将任意 HTML 或其他组件嵌入到子组件中。如果仅存在一个默认插槽,则可以直接在子组件标签上使用 `v-slot` 指令: ```html <child-component v-slot="props"> {{ props.someData }} </child-component> ``` 上述代码展示了如何通过 `v-slot` 接收插槽 Props 对象[^1]。需要注意的是,默认插槽支持一种简化写法——省略 `v-slot` 参数: ```html <child-component> Default content here. </child-component> ``` 这种简化的语法适用于不需要显式定义插槽 Props 的场景[^3]。 #### 具名插槽 当需要在一个子组件中提供多个插槽时,可以使用具名插槽。具名插槽通过 `<template>` 标签配合 `v-slot:name` 属性来指定名称: ```html <child-component> <template v-slot:header> Header Content </template> <template v-slot:default> Default Slot Content </template> <template v-slot:footer> Footer Content </template> </child-component> ``` 在此示例中,分别定义了名为 `header`、`default` 和 `footer` 的三个插槽。注意,当涉及多插槽时,应避免混合使用默认插槽的缩写语法,以免引发作用域冲突。 #### 解构插槽 Props 对于复杂的插槽需求,可以通过 JavaScript 的解构特性提取所需的 Props 数据: ```html <child-component v-slot="{ user, actions }"> <div>{{ user.name }}</div> <button @click="actions.logout">Logout</button> </child-component> ``` 此方法提高了代码的可读性和维护性。 --- ### 示例代码 以下是一个综合示例,演示了默认插槽与具名插槽的实际应用: ```vue <!-- 子组件 ChildComponent.vue --> <template> <div class="container"> <!-- 默认插槽 --> <slot></slot> <!-- 具名插槽 --> <header> <slot name="header"></slot> </header> <main> <slot name="content"></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> </template> ``` ```vue <!-- 父组件 ParentComponent.vue --> <template> <ChildComponent> <!-- 默认插槽 --> This is the default slot. <!-- 具名插槽 --> <template v-slot:header> Page Title </template> <template v-slot:content> Main content goes here. </template> <template v-slot:footer> Copyright © 2023 </template> </ChildComponent> </template> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值