mirror of
https://gitee.com/WeBank/fes.js.git
synced 2024-12-02 19:58:18 +08:00
fix: 优化plugin-layout,在编译时探测需要的icon组件,然后按需加载
This commit is contained in:
parent
007647044c
commit
7d1c97aadf
@ -9,6 +9,8 @@ export default (api) => {
|
||||
utils: { Mustache }
|
||||
} = api;
|
||||
|
||||
const helper = require('./node/helper');
|
||||
|
||||
api.describe({
|
||||
key: 'layout',
|
||||
config: {
|
||||
@ -25,7 +27,7 @@ export default (api) => {
|
||||
|
||||
const absRuntimeFilePath = join(namespace, 'runtime.js');
|
||||
|
||||
api.onGenerateFiles(() => {
|
||||
api.onGenerateFiles(async () => {
|
||||
const { name } = api.pkg;
|
||||
|
||||
const HAS_LOCALE = api.hasPlugins(['@fesjs/plugin-locale']);
|
||||
@ -37,6 +39,25 @@ export default (api) => {
|
||||
...(api.config.layout || {})
|
||||
};
|
||||
|
||||
// 路由信息
|
||||
const routes = await api.getRoutes();
|
||||
// 把路由的meta合并到menu配置中
|
||||
userConfig.menus = helper.fillMenuByRoute(userConfig.menus, routes);
|
||||
|
||||
const icons = helper.getIconsFromMenu(userConfig.menus);
|
||||
|
||||
const iconsString = icons.map(
|
||||
iconName => `import ${iconName} from '@ant-design/icons-vue/es/icons/${iconName}'`
|
||||
);
|
||||
api.writeTmpFile({
|
||||
path: join(namespace, 'icons.js'),
|
||||
content: `
|
||||
${iconsString.join(';\n')}
|
||||
export default {
|
||||
${icons.join(',\n')}
|
||||
}`
|
||||
});
|
||||
|
||||
api.writeTmpFile({
|
||||
path: absFilePath,
|
||||
content: Mustache.render(
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const noop = () => {};
|
||||
import * as allIcons from '@ant-design/icons-vue';
|
||||
|
||||
const matchName = (config, name) => {
|
||||
let res = {};
|
||||
@ -21,7 +21,7 @@ const matchName = (config, name) => {
|
||||
return res;
|
||||
};
|
||||
|
||||
export const fillMenuData = (menuConfig, routeConfig, dep = 0) => {
|
||||
export const fillMenuByRoute = (menuConfig, routeConfig, dep = 0) => {
|
||||
dep += 1;
|
||||
if (dep > 3) {
|
||||
throw new Error('[plugin-layout]: menu层级不能超出三层!');
|
||||
@ -39,11 +39,37 @@ export const fillMenuData = (menuConfig, routeConfig, dep = 0) => {
|
||||
menu[prop] = pageConfig[prop];
|
||||
}
|
||||
});
|
||||
// 处理icon
|
||||
if (menu.icon) {
|
||||
const icon = menu.icon;
|
||||
const iconName = `${icon.replace(icon[0], icon[0].toUpperCase())}Outlined`;
|
||||
if (!allIcons[icon]) {
|
||||
menu.icon = iconName;
|
||||
}
|
||||
}
|
||||
if (menu.children && menu.children.length > 0) {
|
||||
menu.children = fillMenuData(menu.children, routeConfig, dep);
|
||||
menu.children = fillMenuByRoute(menu.children, routeConfig, dep);
|
||||
}
|
||||
arr.push(menu);
|
||||
});
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
export function getIconsFromMenu(data) {
|
||||
if (!Array.isArray(data)) {
|
||||
return [];
|
||||
}
|
||||
let icons = [];
|
||||
(data || []).forEach((item = { path: '/' }) => {
|
||||
if (item.icon) {
|
||||
const { icon } = item;
|
||||
icons.push(icon);
|
||||
}
|
||||
if (item.children) {
|
||||
icons = icons.concat(getIconsFromMenu(item.children));
|
||||
}
|
||||
});
|
||||
|
||||
return Array.from(new Set(icons));
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import { reactive, defineComponent } from "vue";
|
||||
import { getRoutes, plugin, ApplyPluginsType } from "@@/core/coreExports";
|
||||
import { plugin, ApplyPluginsType } from "@@/core/coreExports";
|
||||
import BaseLayout from "./views/BaseLayout.vue";
|
||||
import { fillMenuData } from "./helpers";
|
||||
|
||||
const userConfig = reactive({{{REPLACE_USER_CONFIG}}});
|
||||
|
||||
@ -14,8 +13,6 @@ const Layout = defineComponent({
|
||||
initialValue: {},
|
||||
});
|
||||
const localeShared = plugin.getShared("locale");
|
||||
const routeConfig = getRoutes();
|
||||
userConfig.menus = fillMenuData(userConfig.menus, routeConfig);
|
||||
return () => {
|
||||
const slots = {
|
||||
customHeader: () => {
|
||||
|
@ -50,7 +50,7 @@ import { toRefs, computed } from 'vue';
|
||||
import { useRoute, useRouter } from '@@/core/coreExports';
|
||||
import Menu from 'ant-design-vue/lib/menu';
|
||||
import 'ant-design-vue/lib/menu/style/css';
|
||||
import MenuIcon from './MenuIcon'
|
||||
import MenuIcon from './MenuIcon';
|
||||
import { addAccessTag } from '../helpers/pluginAccess';
|
||||
|
||||
export default {
|
||||
|
@ -2,29 +2,21 @@
|
||||
// 使用 ant-design/icons-vue
|
||||
// 使用 本地 svg 图片
|
||||
// 使用 远程 svg 地址
|
||||
import { ref, onMounted } from 'vue';
|
||||
// eslint-disable-next-line import/extensions
|
||||
import Icons from '../icons';
|
||||
// import AntdIcon from '@ant-design/icons-vue/es/components/AntdIcon';
|
||||
export default {
|
||||
props: {
|
||||
icon: String
|
||||
},
|
||||
setup(props) {
|
||||
const AIcon = ref(null);
|
||||
onMounted(()=>{
|
||||
const iconName = props.icon.slice(0, 1).toUpperCase() + props.icon.slice(1) + 'Outlined';
|
||||
import(`@ant-design/icons-vue/es/icons/${iconName}`).then(res=>{
|
||||
AIcon.value = res.default;
|
||||
}).catch(e=>{
|
||||
console.warn(`[fes-layout] icon ${props.icon} 不存在!`)
|
||||
})
|
||||
})
|
||||
return ()=>{
|
||||
if(AIcon.value){
|
||||
return <AIcon.value />
|
||||
const AIcon = Icons[props.icon];
|
||||
return () => {
|
||||
if (AIcon) {
|
||||
return < AIcon />;
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user