chore: init frontend with knowledge module
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
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>
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user