首页 > 解决方案 > 如何避免在类似的 Vue 组件中重复 props?

问题描述

组件结构:

组件结构

我的应用程序中有许多button组件,每个组件都有不同的组件icon(我已将它们放在icons它们自己的组件中,以便我可以在其他地方使用它们)。我希望这些组件在父组件悬停时icon响应悬停事件。

我有一个解决方案,但其中有重复。对于每个按钮(SettingsButtonHelpButton),我发现自己编写hover代码是为了将其传递给icon组件。有没有办法避免这种情况?

单击此处查看 JS 小提琴示例。

const { ref } = Vue;

const HelpIcon = {
    template: `<div :style="{ 'background': hover ? 'blue' : '' }"></div>`,

    props: {
        hover: {
            type: Boolean,
            required: true,
        },
    },
};

const BaseButton = {
    template: `
        <a href="/" @click.prevent>
            <slot name="icon" />

            <span>
                <slot name="text" />
            </span>
        </a>
    `,
};

const HelpButton = {
    components: { BaseButton, HelpIcon },

    // _every_ button has to have `mouseover`, `mouseleave` and `hover` ref
    template: `
        <BaseButton @mouseover="hover = true" @mouseleave="hover = false">
            <template #icon>
                <HelpIcon :hover="hover" />
            </template>

            <template #text>Help</template>
        </BaseButton>
    `,

    setup() {
        // _every_ button has this ref
        const hover = ref(false);
        return { hover };
    }
};

Vue.createApp({
    components: { HelpButton },
}).mount('#app');

标签: vue.jsvuejs3

解决方案


您可以使用mixin类似:

const hoverable={
    props: {
        hover: {
            type: Boolean,
            required: true,
        },
    },   
}

然后将其添加到您的图标混合选项中:

const HelpIcon = {
    template: `<div :style="{ 'background': hover ? 'blue' : '' }"></div>`,
     mixins:[hoverable]
};

还尝试在其中注册事件处理程序,BaseButton然后传递hovervia 作用域插槽:

const BaseButton = {
    template: `
        <a href="/" @click.prevent  @mouseover="hover = true" @mouseleave="hover = false">
            <slot name="icon" :hover="hover" />
          
            <span>
                <slot name="text" />
            </span>
        </a>
    `,
 setup() {
        const hover = ref(false);
        return { hover };
    }
};

然后 :

 <BaseButton >
            <template #icon="{hover}" >
                <HelpIcon :hover="hover" />
            </template>

            <template #text>Help</template>
 </BaseButton>

现场演示


推荐阅读