文章目录
- 一、组件封装
 - 二、使用
 - 三、最终效果(参考)
 - 四、参考
 
一、组件封装
ButtonFold.vue
1、获取父组件的元素,根据元素创建动态插槽
2、插槽中插入父元素标签。默认效果和初始状态相同。
3、当屏幕宽度缩小时,部分按钮通过 dropdown 的方式展示出来,doropdown 默认按钮使用...图标
4、firstHideBtnIndex 边界值可自定义
<!-- 按钮折叠组件 -->
<template>
    <template 
        v-for="(item, index) in btns"
    >
        <slot v-if="isShowBtn(index)" :name="`slot${index}`"></slot>
    </template>
    <a-dropdown 
        :trigger="['click']" 
        v-if="isShowMoreBtns()"
    >
        <a-button type="text">
            <EllipsisOutlined />
        </a-button>
        <template #overlay>
            <a-menu>
                <template 
                    v-for="(item, index) in btns" 
                    :key="index" 
                >
                    <a-menu-item 
                        class="ant-pro-drop-down menu"
                        v-if="index >= Number(firstHideBtnIndex)"
                    >
                        <slot :name="`slot${index}`"></slot>
                    </a-menu-item>
                </template>
            </a-menu>
        </template>
    </a-dropdown>
</template>
<script lang="ts" setup>
import { throttle } from 'lodash-es';
import {
    EllipsisOutlined,
} from '@ant-design/icons-vue';
import { useRouter } from 'vue-router';
const slots = useSlots();
const router = useRouter();
const btns = computed(() => slots.default?.());
const firstHideBtnIndex = ref<number>(Number(btns.value?.length));
btns.value?.forEach((x: any, i: number) => {
    Object.assign(slots, { [`slot${i}`]: () => ([x]) });
});
const isShowBtn = (i: number) => {
    return i < Number(firstHideBtnIndex.value);
};
const isShowMoreBtns = () => {
    return Number(firstHideBtnIndex.value) < Number(btns.value?.length);
};
const foldResiez = throttle((e: any) => {
    setFirstBtnIndex();
}, 400);
const setFirstBtnIndex = () => {
    if (document.body.scrollWidth < 1300 ) {
        firstHideBtnIndex.value = 4;
    } else {
        firstHideBtnIndex.value = Number(btns.value?.length);
    }
};
onBeforeUpdate(() => {
    btns.value?.forEach((x: any, i: number) => {
        Object.assign(slots, { [`slot${i}`]: () => ([x]) });
    });
    setFirstBtnIndex();
});
onMounted(() => {
    window.addEventListener('resize', foldResiez, false);
});
onBeforeUnmount(() => {
    window.removeEventListener('resize', foldResiez, false);
});
</script>
<style scoped lang="scss"></style>
 
二、使用
- 当按钮较多时,在按钮外部使用 ButtonFold 组件包裹。
 - 屏幕宽度变化在 ButtonFold 中监测
 
import ButtonFold from './ButtonFold.vue';
<button-fold>
	<button>1</button>
	<button>2</button>
	<button>3</button>
	<button>4</button>
	<button>5</button>
	<button>6</button>
	<button>7</button>
	<button>8</button>
</button-fold>
 
三、最终效果(参考)

四、参考
- 画面宽度发生变化,导致的按钮换行
 - 插槽 Slots
 



















