|
@@ -9,10 +9,11 @@
|
|
|
prefix-icon="Search"
|
|
|
clearable
|
|
|
@input="searchInput"
|
|
|
- placeholder="菜单太难找?在这里搜索。"></el-input>
|
|
|
+ placeholder="菜单太难找?在这里搜索。"/>
|
|
|
</div>
|
|
|
<el-scrollbar :style="barHeight">
|
|
|
<el-menu
|
|
|
+ v-if="rendering"
|
|
|
ref="menuRef"
|
|
|
router
|
|
|
:collapse-transition="false"
|
|
@@ -36,62 +37,39 @@ import Logo from '../HeaderV2/Logo.vue'
|
|
|
import XEUtils from "xe-utils";
|
|
|
import router from '@/router'
|
|
|
import sleep from "@/utils/sleep";
|
|
|
+import {treeSearch} from "@/utils/array-utils";
|
|
|
+import {useCompRef} from "@/utils/useCompRef";
|
|
|
+import {ElMenu} from "element-plus";
|
|
|
|
|
|
const menuText: Ref<string> = ref('')
|
|
|
-const menuRef = ref()
|
|
|
+const menuRef = useCompRef(ElMenu)
|
|
|
|
|
|
-const data = store.state.user.routes
|
|
|
+const data = store.state['user'].routes
|
|
|
+const rendering = ref(true)
|
|
|
|
|
|
const isSearch = ref<boolean>(false)
|
|
|
const searchData = ref([])
|
|
|
|
|
|
-function filterMenu<D>(data: D[], iterator: (item: D) => boolean) {
|
|
|
- data = JSON.parse(JSON.stringify(data))
|
|
|
+const searchActives = new Set()
|
|
|
|
|
|
- function filterDataByVisible(tempData: D) {
|
|
|
- return tempData.filter(item => {
|
|
|
- if (item.children) {
|
|
|
- item.children = filterDataByVisible(item.children);
|
|
|
- }
|
|
|
- if (item.$visible) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
+const searchInput: (val: string) => void = XEUtils.debounce(async (val: string) => {
|
|
|
+ menuText.value = val;
|
|
|
+ searchActives.clear();
|
|
|
|
|
|
- const traverse = (tempData: D) => {
|
|
|
- tempData.forEach(child => {
|
|
|
- child.$visible = iterator(child)
|
|
|
- if (child.children) traverse(child.children);
|
|
|
- if (!child.$visible && child.children?.length) {
|
|
|
- let $visible = !child.children.some(child => child.$visible);
|
|
|
- child.$visible = $visible === false;
|
|
|
- }
|
|
|
+ if (val) {
|
|
|
+ searchData.value = treeSearch<{ metaTitle: string; }>(data, (item) => {
|
|
|
+ const metaTitle: string = item.metaTitle
|
|
|
+ return metaTitle.includes(val);
|
|
|
});
|
|
|
- };
|
|
|
-
|
|
|
- traverse(data);
|
|
|
- return filterDataByVisible(data);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-let searchActives = new Set()
|
|
|
-const searchInput = XEUtils.debounce(async (val) => {
|
|
|
- menuText.value = val
|
|
|
- searchActives.clear()
|
|
|
-
|
|
|
- searchData.value = filterMenu<{
|
|
|
- metaTitle: string
|
|
|
- }>(data, (item) => {
|
|
|
- const metaTitle: string = item.metaTitle
|
|
|
- return metaTitle.includes(val);
|
|
|
- })
|
|
|
-
|
|
|
- isSearch.value = !!val
|
|
|
-
|
|
|
- await nextTick()
|
|
|
- expandNodes(searchData.value)
|
|
|
-
|
|
|
+ isSearch.value = true
|
|
|
+ await nextTick()
|
|
|
+ expandNodes(searchData.value)
|
|
|
+ } else {
|
|
|
+ searchData.value = []
|
|
|
+ await nextTick()
|
|
|
+ isSearch.value = false
|
|
|
+ smoothScrolling()
|
|
|
+ }
|
|
|
}, 500)
|
|
|
|
|
|
const expandNodes = (treeData) => {
|
|
@@ -103,27 +81,27 @@ const expandNodes = (treeData) => {
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
-
|
|
|
traverse(treeData)
|
|
|
}
|
|
|
|
|
|
const menuLaunch = async path => {
|
|
|
- try {
|
|
|
- await nextTick()
|
|
|
- const li = document.getElementById(path)
|
|
|
- const div = li.children[0]
|
|
|
- const icon = div.getElementsByClassName('el-icon el-sub-menu__icon-arrow')
|
|
|
- if (icon.item(0).style.transform === 'none') {
|
|
|
- div.click()
|
|
|
+ await nextTick();
|
|
|
+ const li = document.getElementById(path);
|
|
|
+ const div = li.children[0];
|
|
|
+ const icon = div.getElementsByClassName('el-icon el-sub-menu__icon-arrow');
|
|
|
+ // @ts-ignore
|
|
|
+ if (icon.item(0).style.transform === 'none') {
|
|
|
+ try {
|
|
|
+ // @ts-ignore
|
|
|
+ div!.click();
|
|
|
+ } catch (e) {
|
|
|
}
|
|
|
- } catch (e) {
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-const expandOneMenu = computed(() => store.state.app.expandOneMenu)
|
|
|
+const expandOneMenu = computed<boolean>(() => store.state['app'].expandOneMenu)
|
|
|
const route = useRoute()
|
|
|
-const isCollapse = computed(() => store.state.app.isCollapse)
|
|
|
+const isCollapse = computed<boolean>(() => store.state['app'].isCollapse)
|
|
|
|
|
|
const expandMenu = () => {
|
|
|
if (isCollapse.value) {
|
|
@@ -142,10 +120,10 @@ const barHeight = reactive({
|
|
|
height: ''
|
|
|
})
|
|
|
|
|
|
-const activeMenu = computed(() => {
|
|
|
+const activeMenu = computed<string>(() => {
|
|
|
const {meta, path} = route
|
|
|
if (meta['activeMenu']) {
|
|
|
- return meta['activeMenu']
|
|
|
+ return meta['activeMenu'] as string
|
|
|
}
|
|
|
return path
|
|
|
})
|
|
@@ -165,7 +143,7 @@ watch(() => router.currentRoute.value, async () => {
|
|
|
menuText.value = ''
|
|
|
isSearch.value = false
|
|
|
await nextTick()
|
|
|
- await menuRef.value.handleResize()
|
|
|
+ await sleep(200)
|
|
|
smoothScrolling()
|
|
|
})
|
|
|
|