xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

vue get slot props All In One

vue get slot props All In One

bug

要使用默认 slotProps, 不可以给 slot 命名 ✅

独占默认 slot 的缩写语法

https://cn.vuejs.org/v2/guide/components-slots.html#独占默认插槽的缩写语法

demo

  1. old version 2.6.0-
<div id="app">
  <my-parent>
    <template slot-scope="{signal}">
      <my-child :signal="signal"></my-child>
      <my-child :signal="signal"></my-child>
    </template>
  </my-parent>
</div>



  1. new version 2.6.0+

https://medium.com/the-vue-point/vue-2-6-released-66aa6c8e785e

  <my-parent>
    <template v-slot="{ signal }">
      <my-child :signal="signal"></my-child>
      <my-child :signal="signal"></my-child>
    </template>
  </my-parent>

子组件通过 slot ( v-slot) 获取父组件的 props



slot 有 name 导致无法读取 slotProps bug ❌

<template>
    <section class="slot-test-container">
        <h1>groupIndex = {{groupIndex}}</h1>
        <span>{{JSON.stringify(groupItem, null, 4)}}</span>
        <!-- slot 没有 name, 默认 slotProps -->
        <!-- <slot
            :groupIndex="0"
            :groupItem="{key: 'value'}">
        </slot> -->
        <!-- slot 有 name,  bug ??? slot props -->
        <!-- <slot
            :groupIndex="0"
            :groupItem="{key: 'value'}"
            name="slot-test-slot">
        </slot> -->
    </section>
</template>

<script>

export default {
    name: 'SlotTest',
    components: {
        //
    },
    props: {
        groupIndex: {
            type: Number,
            default: 0,
        },
        groupItem: {
            type: Object,
            default: () => ({}),
        },
    },
    data () {
        return {
            //
        };
    },
    computed: {
        //
    },
    watch: {
        //
    },
    mounted () {
        this.init();
    },
    methods: {
        init () {
            console.log('SlotTest', this.groupIndex, this.groupItem);
        },
    },
};

</script>

<style lang="scss" scoped>

.slot-test-container {
    box-sizing: border-box;
    display: flex;
    flex-flow: row nowrap;
    align-items: flex-start;
    justify-content: center;
    width: 660px;
    height: 220px;
}

</style>


    <el-form-item
        label="创意文案"
        :prop="`creativeList.${creativeIndex}.titleList`"
        :rules="[
            {
                required: true,
                validator: titleListValidator,
                trigger: 'blur',
            },
        ]">
        <!-- 多个文案组 -->
        <TextAddGroup
            :groupList="textGroupList"
            @remove="removeTextGroup"
            @add="addTextGroup">
            <!-- <template
                slot-scope="slotProps">
                ???{{ slotProps.groupIndex }} -->
            <template v-slot="{groupIndex, groupItem}">
                <SlotTest
                    :groupIndex="groupIndex"
                    :groupItem="groupItem"
                />
                <!-- <CreativeText2
                    :groupIndex="groupIndex"
                    ref="creativeTextRef"
                    slot="text-add-group-slot"
                    :creativeObj="creative"
                    :sensitiveList="sensitiveList"
                    :customWords="customWords"
                    :wordList="wordList"
                    :prohibitedList="prohibitedList"
                    @validate-field="validateFieldByKey"
                    @change-title-type="changeTitleButtonType('title')"
                /> -->
            </template>
            <!-- <CreativeText2
                :groupIndex="groupIndex"
                ref="creativeTextRef"
                slot="text-add-group-slot"
                :creativeObj="creative"
                :sensitiveList="sensitiveList"
                :customWords="customWords"
                :wordList="wordList"
                :prohibitedList="prohibitedList"
                @validate-field="validateFieldByKey"
                @change-title-type="changeTitleButtonType('title')"
            /> -->
        </TextAddGroup>
    </el-form-item>

<template>
    <section class="text-add-group-container">
        <div
            class="text-add-group-box"
            v-for="(item, index) in groupList"
            :key="(index)">
            <slot
                :groupIndex="index"
                :groupItem="item"
                class="text-add-group-slot">
            </slot>
            <!-- <slot
                :groupIndex="index"
                :groupItem="item"
                class="text-add-group-slot"
                name="text-add-group-slot">
            </slot> -->
            <div
                v-if="groupList.length > 1"
                class="delete-icon-box">
                <icon-svg
                    icon-class="delete"
                    class="delete-icon"
                    @click="handleRemove(index)"
                />
            </div>
        </div>
        <div
            v-if="leftNum > 0"
            class="add-group-btn"
            @click="handleAdd">
            <span class="add-group-btn-text">
                <icon-svg icon-class="tianjia1" />
                <span>还可以添加{{leftNum}}组</span>
            </span>
        </div>
    </section>
</template>

<script>

export default {
    name: 'TextAddGroup',
    components: {
        //
    },
    props: {
        groupList: {
            type: Array,
            default: () => [],
        },
        limit: {
            type: Number,
            default: 3,
        },
    },
    data () {
        return {
            //
        };
    },
    watch: {
        //
    },
    computed: {
        leftNum () {
            return this.limit - this.groupList.length;
        },
    },
    mounted () {
        this.init();
    },
    methods: {
        init () {
            //
        },
        handleAdd () {
            this.$emit('add');
        },
        handleRemove (index) {
            this.$emit('remove', index);
        },
    },
};
</script>


<style lang="scss" scoped>

.text-add-group-container {
    box-sizing: border-box;
    display: flex;
    flex-flow: column nowrap;
    .text-add-group-box {
        box-sizing: border-box;
        width: calc(100% - 60px);
        display: inline-flex;
        flex-flow: row nowrap;
        margin-bottom: 10px;
        .text-add-group-slot {
            box-sizing: border-box;
            // width: 660px;
        }
        .delete-icon-box {
            box-sizing: border-box;
            display: flex;
            flex-flow: row nowrap;
            align-items: center;
            justify-content: center;
            margin-left: 10px;
            min-width: 40px;
            height: 32px;
            // &:hover {
            //     background: #F9F9F9;
            //     border-radius: 4px;
            //     border: 1px solid #EBEEF5;
            // }
            .delete-icon {
                width: 15px;
                height: 15px;
                color: #909399;
                // background: #909399;
                cursor: pointer;
            }
        }
    }
    .add-group-btn {
        width: calc(100% - 50px);
        min-width: calc(660px);
        box-sizing: border-box;
        display: flex;
        align-items: center;
        justify-content: center;
        height: 40px;
        background: #FFFFFF;
        border-radius: 4px;
        border: 1px dashed #999999;
        cursor: pointer;
        .add-group-btn-text {
            text-align: center;
            cursor: pointer;
            height: 17px;
            font-size: 12px;
            color: #333333;
            line-height: 17px;
        }
    }
}

</style>


refs

https://stackoverflow.com/questions/45180114/how-to-pass-props-using-slots-from-parent-to-child-vuejs

https://www.cnblogs.com/xgqfrms/p/14494417.html



©xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2021-08-11 00:34  xgqfrms  阅读(88)  评论(4编辑  收藏  举报