项目需求:
横向菜单栏,菜单过多时自动折叠到下拉框,可伸缩。
参考:
文章
解决方案:
使用了element-plus组件
<template>
<div class="box">
<el-menu :default-active="activeIndex" class="el-menu-demo menuList" mode="horizontal" @select="handleSelect">
<el-menu-item v-for="item in data" :key="item.id" class="menuItem" :index="item.id">{{ item.text }}</el-menu-item>
<el-sub-menu v-if="moreArr.length > 0" class="menuItem">
<el-menu-item v-for="i in moreArr" :key="i.id" :index="i.id">{{
i.text
}}</el-menu-item>
</el-sub-menu>
</el-menu>
</div>
</template>
<script setup>
import { reactive, ref, computed, onMounted, watch } from "vue";
let activeIndex = ref('1')
let data = reactive([
{
id: "1",
text: "处理中心",
},
{
id: "2",
text: "处理中心2ssewfergreg",
},
{
id: "3",
text: "处理中心3",
},
{
id: "4",
text: "处理中心4",
},
{
id: "5",
text: "处理中心5",
},
{
id: "6",
text: "处理中心6",
},
{
id: "7",
text: "处理中心7",
},
{
id: "8",
text: "处理中心8",
},
{
id: "9",
text: "处理中心9",
},
{
id: "10",
text: "处理中心10",
},
{
id: "11",
text: "处理中心11",
},
{
id: "12",
text: "处理中心12",
},
{
id: "13",
text: "处理中心13",
},
{
id: "14",
text: "处理中心14",
},
{
id: "15",
text: "处理中心15",
},
{
id: "16",
text: "处理中心16",
},
{
id: "17",
text: "处理中心17",
},
{
id: "18",
text: "处理中心18",
},
])
let newArr = reactive([])
let existing = ref(0)
let moreArr = reactive([])
let isb = ref(false)
let isr = ref(false)
let resData = reactive([])
let allItemWidth = reactive([])
let isExpanding = ref(false)
let curWindow = ref(0)
onMounted(() => {
resData = JSON.parse(JSON.stringify(data))
const widthList = document.getElementsByClassName("menuItem")
for (let i = 0; i < widthList.length; i++) {
if (widthList[i].clientWidth) {
allItemWidth.push(widthList[i].clientWidth);
}
}
initMenu()
})
function initMenu() {
data = resData
let newArr = JSON.parse(JSON.stringify(data));
let menuitem = []
if (isExpanding.value) {
menuitem = allItemWidth.slice(0, data.length - 1)
} else {
menuitem = document.getElementsByClassName("menuItem");
}
let widthArr = [];
for (let i = 0; i < menuitem.length; i++) {
if (menuitem[i]) {
widthArr.push(menuitem[i]);
}
}
if (isExpanding.value) {
isReduce(widthArr);
} else {
isbeyond(widthArr)
}
let arr = [];
if (existing.value != 0) {
arr = newArr.splice(existing.value, newArr.length - 1);
}
moreArr = arr;
}
function handleSelect(key, keyPath) {
console.log(key, keyPath);
}
function sum(arr) {
return arr.reduce(function (prev, curr, idx, arr) {
return prev + curr;
});
}
function isbeyond(widthArr) {
let menu = document.getElementsByClassName("menuList");
if (sum(widthArr) >= menu[0].clientWidth && !isExpanding.value) {
isb.value = true;
let newArr = data.slice(0, data.length - 1);
let newWidthArr = widthArr.slice(0, data.length - 1);
data = newArr;
isbeyond(newWidthArr);
} else {
if (isb.value) {
data = data.slice(0, widthArr.length - 1)
existing.value = data.length;
}
}
}
function isReduce(widthArr) {
let menu = document.getElementsByClassName("menuList");
let addWidthArr = allItemWidth.slice(0, widthArr.length)
if (sum(addWidthArr) <= menu[0].clientWidth && isExpanding.value) {
isr.value = true;
let newArr = resData.slice(0, addWidthArr.length + 1);
let newWidthArr = allItemWidth.slice(0, addWidthArr.length + 1);
data = newArr;
isReduce(newWidthArr);
} else {
if (isr.value) {
data = data.slice(0, widthArr.length - 1)
existing.value = data.length;
}
}
}
window.onresize = () => {
isExpanding.value = document.documentElement.clientWidth > curWindow.value ? true : false
curWindow.value = document.documentElement.clientWidth
if (data.length > 1 && data.length < resData.length) {
initMenu()
}
}
</script>
<style scoped>
.box {
background: #fff;
width: 80%;
height: 100px;
margin: 0 auto;
}
</style>