Skip to content

Commit fcd6419

Browse files
committed
fix: 修复/更新 barleft 行为
修复:之前只有首次进入网页会记录当前所在栏目,并让当前栏目在高度不够时保持开启(除非手动关闭),现在切换路由时候会记录新的所在栏目 并在后续保持开启 更新:barleft 会持续增长。故现在不再限制 barleft 总展开高度小于 windows.innerHeight,只小于 main 高度
1 parent bda91ce commit fcd6419

File tree

2 files changed

+70
-71
lines changed

2 files changed

+70
-71
lines changed

app.vue

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,21 @@ router.afterEach((to, _from) => {
3131
});
3232
3333
const { $mitt } = useNuxtApp();
34-
const bodyRef = useTemplateRef('mainBody');
34+
const mainRef = useTemplateRef('mainBody');
35+
const heightRef = useTemplateRef('dMainBody');
3536
onMounted(() => {
36-
const mutationObserver =
37-
window.MutationObserver ||
38-
window.WebKitMutationObserver ||
39-
window.MozMutationObserver;
40-
const observer = new mutationObserver(() => {
41-
$mitt.emit('routeSwitching');
42-
});
43-
observer.observe(bodyRef.value, {
44-
childList: true
45-
});
37+
new ResizeObserver(() => {
38+
$mitt.emit('mainDomChange', mainRef.value.clientHeight);
39+
}).observe(heightRef.value);
4640
});
4741
</script>
4842

4943
<template>
5044
<NuxtLayout>
51-
<div ref="mainBody" class="flex-1 pl-[1px]"><NuxtPage /></div>
45+
<div ref="mainBody" class="flex-1 pl-[1px]">
46+
<div ref="dMainBody">
47+
<NuxtPage />
48+
</div>
49+
</div>
5250
</NuxtLayout>
5351
</template>

components/bar/BarLeft.vue

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup>
2-
const { tm, locale } = useI18n();
2+
const { tm, _locale } = useI18n();
33
44
const getComp = computed(() => {
55
const textValue = tm('BarLeft');
@@ -75,6 +75,8 @@ const rowHeight = 32;
7575
const chunkPading = 6;
7676
const rowHeightpx = `${rowHeight}px`;
7777
78+
const thisElSubEnum = ref(undefined);
79+
7880
const route = useRoute();
7981
8082
const openMenu = (MenuOpenEvent) => {
@@ -87,67 +89,75 @@ const openMenu = (MenuOpenEvent) => {
8789
break;
8890
} else {
8991
height -=
90-
navigationList.value[item].children.length * rowHeight - chunkPading;
92+
navigationList.value[item].children.length * rowHeight + chunkPading;
9193
closeMenu(item);
9294
}
9395
}
9496
openMenuList.add(MenuOpenEvent);
9597
};
9698
97-
const deleteSetItem = (target, setList) => {
98-
for (const item of setList) {
99-
if (item === target) {
100-
setList.delete(item);
101-
break;
102-
}
103-
}
104-
};
105-
10699
const closeMenu = (MenuOpenEvent) => {
107-
deleteSetItem(MenuOpenEvent, openMenuList);
100+
openMenuList.delete(MenuOpenEvent);
108101
menuRef.value.close(MenuOpenEvent);
109102
};
110103
111-
const highlyIsQualified = (height) => {
104+
const highlyIsQualified = (
105+
height,
106+
mainHeight = menuDivRef.value.parentNode.parentNode.nextElementSibling
107+
.clientHeight
108+
) => {
112109
// 在中心内容长度小于window.innerHeight时,回到首页弹窗不可能出来
113110
// 此时高度比较参照中心内容长度即可,不需要算上弹窗和底栏
114111
// 中心内容长度大于window.innerHeight时,总长度要加上底栏和弹窗和1px的弹窗下边距与window.innerHeight对比
115-
if (
116-
height + rowHeight * 2 + 1 < window.innerHeight &&
117-
height <
118-
menuDivRef.value.parentNode.parentNode.nextElementSibling.clientHeight
119-
)
120-
return true;
112+
if (height < mainHeight) return true;
121113
return false;
122114
};
123115
124116
const { $mitt } = useNuxtApp();
125117
onMounted(() => {
126-
$mitt.on('routeSwitching', () => {
127-
nextTick(() => {
128-
retractMenuBar();
129-
});
118+
$mitt.on('mainDomChange', (newHeight) => {
119+
retractMenuBar(newHeight);
130120
});
131121
});
132122
onBeforeUnmount(() => {
133-
$mitt.off('routeSwitching');
123+
$mitt.off('mainDomChange');
134124
});
135125
136-
const retractMenuBar = () => {
126+
const changeThisElSubEnum = () => {
127+
let thisElSubEnmu_cache = undefined;
128+
if (route.path !== '/') {
129+
for (const [index, item] of navigationList.value.entries()) {
130+
if (item.children.find((item1) => route.path.includes(item1.url))) {
131+
// 记录当前所在
132+
thisElSubEnmu_cache = index;
133+
break;
134+
}
135+
}
136+
if (thisElSubEnum.value !== undefined)
137+
openMenuList.add(String(thisElSubEnum.value));
138+
139+
openMenuList.delete(String(thisElSubEnmu_cache));
140+
thisElSubEnum.value = thisElSubEnmu_cache;
141+
}
142+
};
143+
144+
const autoFold = (newHeight) => {
137145
let height = menuDivRef.value.clientHeight;
138146
for (const item of openMenuList) {
139-
if (highlyIsQualified(height)) {
147+
if (highlyIsQualified(height, newHeight)) {
140148
break;
141149
} else {
142150
if (openMenuList.size === 1) break;
143151
height -=
144-
navigationList.value[item].children.length * rowHeight - chunkPading;
152+
navigationList.value[item].children.length * rowHeight + chunkPading;
145153
closeMenu(item);
146154
}
147155
}
148-
// for (const item of openMenuList) {
149-
// menuRef.value.open(item);
150-
// }
156+
};
157+
158+
const retractMenuBar = (newHeight) => {
159+
changeThisElSubEnum(newHeight);
160+
autoFold(newHeight);
151161
};
152162
onMounted(() => {
153163
// 每次缩放改变的时候,判断有没有栏目需要缩回去,先展开的,优先缩进
@@ -156,42 +166,32 @@ onMounted(() => {
156166
return () => {
157167
if (timeoutID !== undefined) clearTimeout(timeoutID);
158168
timeoutID = setTimeout(() => {
159-
retractMenuBar();
169+
autoFold();
160170
timeoutID = undefined;
161171
}, 40);
162172
};
163173
})();
164-
let height = menuDivRef.value.clientHeight;
165-
// 初次加载的时候尝试打开当前栏目分类
166-
// 记一下目前所在分类的title
167-
let thisElSubEnum = null;
168-
for (const [index, item] of navigationList.value.entries()) {
169-
if (thisElSubEnum === null) {
170-
if (item.children.find((item1) => route.path.includes(item1.url))) {
171-
// 当前所在不入列尾
172-
thisElSubEnum = index;
173-
} else {
174-
openMenuList.add(String(index));
175-
}
176-
} else {
177-
openMenuList.add(String(index));
178-
}
179-
}
180-
// 然后在剩余空间里按顺序遍历栏目,能展开尽量展开
181-
// 默认全部展开,根据空间从下向上依次关闭,跳过当前栏目
182-
for (const [index, item] of reverseIterator(navigationList.value)) {
183-
if (highlyIsQualified(height)) {
184-
break;
185-
}
186-
if (thisElSubEnum !== index) {
187-
height = height - (item.children.length * rowHeight + chunkPading);
188-
closeMenu(String(index));
189-
}
174+
// 默认全部展开,找到并记一下目前所在栏目
175+
for (let i = 0; i < navigationList.value.length; i++) {
176+
openMenuList.add(String(i));
190177
}
191178
// 判断当前所在位置是否需要回到顶部按钮
192-
returnFromTop();
193-
// 挂载上面监听器
179+
// 挂载监听器
194180
window.addEventListener('scroll', returnFromTop);
181+
182+
// 当前会触发一次retractMenuBar无需手动处理
183+
// // 然后在剩余空间里按顺序遍历栏目,能展开尽量展开
184+
// // 默认全部展开,根据空间从下向上依次关闭,跳过当前栏目
185+
// let height = menuDivRef.value.clientHeight;
186+
// for (const [index, item] of reverseIterator(navigationList.value)) {
187+
// if (highlyIsQualified(height)) {
188+
// break;
189+
// }
190+
// if (thisElSubEnum.value !== index) {
191+
// height -= item.children.length * rowHeight + chunkPading;
192+
// closeMenu(String(index));
193+
// }
194+
// }
195195
});
196196
197197
const returnFromTop = (() => {
@@ -234,6 +234,7 @@ const backToTopBtnShow = ref(false);
234234
:default-openeds="defaultOpeneds"
235235
@close="closeMenu"
236236
@open="openMenu">
237+
<!-- 它的 index 要求是字符串不然控制台发警告 -->
237238
<el-sub-menu
238239
v-for="(item, index) in navigationList"
239240
:key="`barleft-1-link-${index}`"

0 commit comments

Comments
 (0)