vue slot插槽

v-slot
用于声明具名插槽 或 作用域插槽;简写模式:v-slot:top > #top

<slot />
在封装组件时,可以通过<slot>标签定义插槽,从而给预留内容占位;
插槽的html, css内容写在调用组件的父组件中;

匿名插槽

子组件.vue

<template>
    <div class="card-wrapper">
        <div class="top">标题</div>
        <slot></slot>              // 占位符,预留内容
    </div>
</template>
<template>
     <Left>
        <h4>{{ msg1 }}</h4>
    </Left>
    
    <Left>
        <h5>{{ msg2 }}</h5>
    </Left>
</template>

<script>
import Left from "./components/Left.vue";
export default {
    components: {
        Left,
    },
    data() {
        return {
            msg1: "给h4的内容",
            msg2: "这是给h5...",
        };
    },
};
</script>

如果调用组件没有传内容,可默认内容

父组件.vue

<template>
     <Left></Left>
</template>

子组件.vue

<template>
    <div class="card-wrapper">
        <div class="top">标题</div>
        <slot>没有内容</slot>
    </div>
</template>

具名插槽

在封装组件时可以预留多个插槽,为每个<slot>插槽指定具体的name名称;

子组件.vue

<template>
    <div class="card-wrapper">

        <div class="top">
            <slot name="top"></slot>
        </div>

        <slot>默认内容</slot>  // 等价于 <slot name="default">默认内容</slot>

        <div class="bot">
            <slot name="bot"></slot>
        </div>

    </div>
</template>

父组件.vue

<template>
     <Left>
        <template #top>
            <div>商品1</div>
        </template>

        <div style="height:100px;">
            {{ msg }}
        </div>
        
        <template v-slot:bot>
            <div style="color:red">2022-04-28</div>
        </template>
     </Left>
</template>

作用域插槽

获取子组件插槽的数据

子组件.vue

<template>
    <div class="card-wrapper">
        <div class="top">
            <slot name="top"></slot>
        </div>

        <slot :content="info"></slot>

        <div class="bot">
            <slot name="bot" :timer="stampTime"></slot>
        </div>

    </div>
</template>
<script>
export default {
    props:{
        info:Object,
        stampTime: Object,
    }
}
</script>

父组件.vue

    <Left :info="info" :stamp-time="timer">
        <template #top>
            <div>商品1</div>
        </template>

        <template #default="{ content }">
            <div>{{ content.name }}</div>
            <div>{{ content.desc }}</div>
        </template>

        <template #bot="{ timer }">
            <div style="color: red">
                {{ timer.hour }}-{{ timer.min }}-{{ timer.sec }}
            </div>
        </template>
    </Left>

<script>
import Left from "./components/Left.vue";
export default {
    components: { Left },
    data() {
        return {
            info: {
                name: "一件不同寻常的商品",
                desc: "奇幻、科幻、梦幻",
            },
            timer: {
                hour: "12",
                min: "59",
                sec: "59",
            },
        };
    },
};
</script>
<Left>
    <template #[whichSlot]>
         <div>这是内容</div>
    </template>
</Left>

<script>
import Left from "./components/Left.vue";
export default {
    components: { Left },
    data() {
        return {
          whichSlot: 'default'
        };
    },
};
</script>
透传命名插槽 和 作用域插槽
<template>
    <my-input v-model="searchValue" placeholder="请输入">
        <template #addonBefore>
            <StrikethroughOutlined />
        </template>
    </my-input>
</template>

<script lang="ts" setup>
import { StrikethroughOutlined } from "@ant-design/icons-vue";
</script>
<template>
  <a-input ref="inputRef" v-bind="$attrs">
    <!-- 
        1. UI组件的命名插槽 
        <template #addonBefore>
            <StrikethroughOutlined />
        </template>
    -->

    <!-- 
        2. 将自定义组件的命名插槽 传递给 UI组件的命名插槽;
        这种方案在没有传递内容时, 依然给UI组件的命名插槽addonBefore传了空内容的<slot name="before"/>标签过去;

        <template #addonBefore>
            <slot name="before"></slot>
        </template>
    -->

    <!-- 3. 将传递给自定义组件标签上的所有属性和方法,绑定透传给UI组件上 -->
    <template v-for="(value, slotName) in $slots" #[slotName]="slotData">
      <!-- 再将UI组件的插槽数据slotData重新绑定到自定义组件的命名插槽上 -->
      <slot :name="slotName" v-bind="slotData || {}"></slot>
    </template>

  </a-input>
</template>

<script setup>
import { ref } from "vue";
const inputRef = ref(null);
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容