VUE3之Component(二)

插槽

基本使用:

使用slot标签在子组件中定义一个插槽:

<template>
    <div>
        <h2>组件的开始</h2>
        <slot></slot>
        <h2>组建的结束</h2>
    </div>
</template>

在父组件中使用这个子组件,并在子组件标签中放入插槽元素:

<template>
    <div>
        <my-slot-cpn>
            <button>我是按钮</button>
            <my-button/>
        </my-slot-cpn>
    </div>
</template>

在slot标签中添加元素可以指定插槽的默认元素:

<template>
    <div>
        <h2>组件的开始</h2>
        <slot>
            <i>我是默认的i元素</i>
        </slot>
        <h2>组建的结束</h2>
    </div>
</template>

具名插槽

通过给slot标签增加name属性来设置具名插槽:

<template>
    <div class="nav-bar">
        <div class="left">
            <slot name="left"></slot>
        </div>
        <div class="center">
            <slot name="center"></slot>
        </div>
        <div class="right">
            <slot name="right"></slot>
        </div>
    </div>
</template>

使用过程中通过template的v-slot属性来指定使用某一个插槽:

<template>
    <div>
        <nav-bar :name="name">
            <template v-slot:left>
                <button>左边的按钮</button>
            </template>
            <template v-slot:center>
                <h2>我是标题</h2>
            </template>
            <template v-slot:right>
                <button>右边的按钮</button>
            </template>
        </nav-bar>
    </div>
</template>

动态命名插槽:可以结合props来动态指定一个插槽的名称:

// NavBar.vue
<template>
    <div class="nav-bar">
        <div class="addition">
            <slot :name="name"></slot>
        </div>
    </div>
</template>

<script>
    export default {
        props:{
            name:String
        }
    }
</script>

// App.vue
<template>
    <div>
        <nav-bar :name="name">
            <template v-slot:[name]>
                <button>动态名称</button>
            </template>
        </nav-bar>
    </div>
</template>

<script>
import NavBar from "./NavBar.vue";
    export default {
        components:{
            NavBar
        },
        data() {
            return {
                name:"sk"
            }
        },
    }
</script>

插槽有默认的名称default。

v-slot:的缩写是#

作用域插槽

作用域的概念是:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的;

在slot标签中增加属性,此属性的值可以在父组件中通过template的v-slot获取到一个实例(如slotProps),并通过slotProps来访问slot的属性:

// ShowNames.vue
<template>
    <div>
        <template v-for="(item,index) in names">
            <slot :item="item" :index="index"></slot>
        </template>
    </div>
</template>

<script>
    export default {
        props:{
            names:{
                type: Array,
                default:()=>[]
            }
        }
    }
</script>

// App.vue
<template>
    <div>
        <show-names :names="names">
            <template v-slot="slotProps">
                <button>{{slotProps.item}}-{{slotProps.index}}</button>
            </template>
        </show-names>
    </div>
</template>

如果是具名插槽,在父组件的template中可以指定某一个具体的名称:

<template v-slot:left="slotProps">

独占默认插槽的缩写:如果只有一个插槽,并且是非具名的,可以有以下缩写

        <show-names :names="names" v-slot="slotProps">
                <button>{{slotProps.item}}-{{slotProps.index}}</button>
        </show-names>

发表评论