Files
film-management-frontend/src/modules/base/pages/main/components/bmenu.tsx
T

154 lines
3.0 KiB
TypeScript

import { defineComponent, h, watch } from 'vue';
import { useBase } from '/$/base';
import { useCool } from '/@/cool';
import { debounce } from 'lodash-es';
export default defineComponent({
name: 'b-menu',
props: {
keyWord: String
},
setup(props) {
const { router, route, browser, refs, setRefs } = useCool();
const { menu, app } = useBase();
// 页面跳转
function onSelect(url: string) {
if (url != route.path) {
router.push(url);
}
// 小屏下点击收起左侧菜单
if (browser.isMini) {
app.fold(true);
}
}
// 渲染子菜单
function renderMenu() {
function deep(list: Menu.Item[], show?: boolean) {
const keyWord = props.keyWord?.toLowerCase() || '';
function filterMenu(item: Menu.Item): boolean {
if (!item.isShow) return false;
if (show) {
return true;
}
if (item.meta?.label?.toLowerCase().includes(keyWord)) return true;
if (item.children) {
return item.children.some(filterMenu);
}
return false;
}
return list.filter(filterMenu).map(e => {
if (e.meta?.label?.toLowerCase().includes(keyWord)) {
show = true;
}
const item = (e: Menu.Item) => {
const arr = [
<cl-svg name={e.icon} size={18} />,
<span class="ml-4 tracking-wider text-[14px] mr-auto text-ellipsis overflow-hidden whitespace-nowrap">
{e.meta?.label}
</span>
];
if (e.type == 1 && e.badge) {
arr.push(
<div class={['b-menu__badge', `is-${e.badgeColor}`]}>
<span>{e.badge}</span>
</div>
);
}
return arr;
};
if (e.type == 0) {
return h(
<el-sub-menu />,
{
index: String(e.id),
key: e.id,
popperClass: 'app-slider__menu'
},
{
title() {
return item(e);
},
default() {
return deep(e.children || [], show);
}
}
);
} else {
return h(
<el-menu-item />,
{
index: e.meta?.isHome ? '/' : e.path,
key: e.id
},
{
default() {
return item(e);
}
}
);
}
});
}
return deep(menu.list);
}
// 展开所有
const expand = debounce(() => {
if (!props.keyWord) {
return;
}
const deep = (list: Menu.Item[]) => {
list.forEach(e => {
if (e.type == 0) {
try {
refs.menu?.open(String(e.id));
} catch (err) { }
if (e.children) {
deep(e.children);
}
}
});
};
deep(menu.list);
}, 300);
watch(() => props.keyWord, expand);
return () => {
return (
<div class="app-slider__menu">
<el-menu
ref={setRefs('menu')}
default-active={route.path}
background-color="transparent"
collapse-transition={false}
collapse={browser.isMini ? false : app.isFold}
onSelect={onSelect}
popper-offset={10}
>
{renderMenu()}
</el-menu>
</div>
);
};
}
});