mirror of
https://gitee.com/log4j/pig-ui.git
synced 2024-12-23 13:43:51 +08:00
admin-22.05.01:重构路由,解决部分No match found for location with path xxx
This commit is contained in:
parent
faf372a8b9
commit
6eaad912f5
@ -16,7 +16,7 @@
|
|||||||
- 🎯 优化 去掉开发环境 i18n 控制台警告,页面代码:[i18n/index.ts](https://gitee.com/lyt-top/vue-next-admin/blob/master/src/i18n/index.ts)
|
- 🎯 优化 去掉开发环境 i18n 控制台警告,页面代码:[i18n/index.ts](https://gitee.com/lyt-top/vue-next-admin/blob/master/src/i18n/index.ts)
|
||||||
- 🎯 优化 `NextLoading.start()` 方法,防止第一次进入界面时出现短暂空白
|
- 🎯 优化 `NextLoading.start()` 方法,防止第一次进入界面时出现短暂空白
|
||||||
- 🎯 优化 地址栏有参数退出登录,再次登录不跳之前界面问题 `src/layout/navBars/breadcrumb/user.vue`
|
- 🎯 优化 地址栏有参数退出登录,再次登录不跳之前界面问题 `src/layout/navBars/breadcrumb/user.vue`
|
||||||
- 🎯 优化 `SvgIcon` 组件,防止 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题
|
- 🎯 优化 `SvgIcon` 组件,防止 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题,工作流不可连线问题
|
||||||
- 🎯 优化 [wangEditor](https://www.wangeditor.com/) 更新到 v5,[vue3 版本线上示例中 wangeditor 富文本编辑器 demo 实例,无法换行#I5565B](https://gitee.com/lyt-top/vue-next-admin/issues/I5565B),感谢@[jenchih](https://gitee.com/jenchih)
|
- 🎯 优化 [wangEditor](https://www.wangeditor.com/) 更新到 v5,[vue3 版本线上示例中 wangeditor 富文本编辑器 demo 实例,无法换行#I5565B](https://gitee.com/lyt-top/vue-next-admin/issues/I5565B),感谢@[jenchih](https://gitee.com/jenchih)
|
||||||
- 🎯 优化 [在关闭 tagview 时,高度刷新时会会变化,出现滚动条](https://gitee.com/lyt-top/vue-next-admin/issues/I55FHM),感谢[张松](https://gitee.com/zs310071113)
|
- 🎯 优化 [在关闭 tagview 时,高度刷新时会会变化,出现滚动条](https://gitee.com/lyt-top/vue-next-admin/issues/I55FHM),感谢[张松](https://gitee.com/zs310071113)
|
||||||
- 🎉 新增 [vuex](https://vuex.vuejs.org/) 替换成 [pinia](https://pinia.vuejs.org/getting-started.html)
|
- 🎉 新增 [vuex](https://vuex.vuejs.org/) 替换成 [pinia](https://pinia.vuejs.org/getting-started.html)
|
||||||
@ -31,6 +31,7 @@
|
|||||||
- 🐞 修复 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题
|
- 🐞 修复 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题
|
||||||
- 🐞 修复 `router.push` 路径找不到时报错问题,`404、401 界面` 已移入到 `main` 主布局里(之前全屏)
|
- 🐞 修复 `router.push` 路径找不到时报错问题,`404、401 界面` 已移入到 `main` 主布局里(之前全屏)
|
||||||
- 🐞 修复 [全局修改组件大小失效了](https://gitee.com/lyt-top/vue-next-admin/issues/I551RP),感谢[lg_boy](https://gitee.com/lg_boy)
|
- 🐞 修复 [全局修改组件大小失效了](https://gitee.com/lyt-top/vue-next-admin/issues/I551RP),感谢[lg_boy](https://gitee.com/lg_boy)
|
||||||
|
- 🌈 重构 路由(`/src/router/index.ts`)解决 No match found for location with path "xxx"(前端控制,后端控制未解决) 问题
|
||||||
|
|
||||||
## 2.0.2
|
## 2.0.2
|
||||||
|
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="svg-icon-container">
|
<i v-if="isShowIconSvg" class="el-icon" :style="setIconSvgStyle">
|
||||||
<i v-if="isShowIconSvg" class="el-icon" :style="setIconSvgStyle">
|
<component :is="getIconName" />
|
||||||
<component :is="getIconName" />
|
</i>
|
||||||
</i>
|
<img v-else-if="isShowIconImg" :src="getIconName" :style="setIconImgStyle" />
|
||||||
<img v-else-if="isShowIconImg" :src="getIconName" :style="setIconImgStyle" />
|
<i v-else :class="getIconName" :style="setIconSvgStyle" />
|
||||||
<i v-else :class="getIconName" :style="setIconSvgStyle" />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -46,7 +44,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
// 设置图标样式
|
// 设置图标样式
|
||||||
const setIconSvgStyle = computed(() => {
|
const setIconSvgStyle = computed(() => {
|
||||||
return `font-size: ${props.size}px;color: ${props.color};height: 100%;display: flex;align-items: center;`;
|
return `font-size: ${props.size}px;color: ${props.color};`;
|
||||||
});
|
});
|
||||||
// 设置图片样式
|
// 设置图片样式
|
||||||
const setIconImgStyle = computed(() => {
|
const setIconImgStyle = computed(() => {
|
||||||
@ -62,9 +60,3 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.svg-icon-container {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@ -105,7 +105,6 @@ export default {
|
|||||||
logOutConfirm: 'determine',
|
logOutConfirm: 'determine',
|
||||||
logOutCancel: 'cancel',
|
logOutCancel: 'cancel',
|
||||||
logOutExit: 'Exiting',
|
logOutExit: 'Exiting',
|
||||||
logOutSuccess: 'Exit successfully!',
|
|
||||||
},
|
},
|
||||||
tagsView: {
|
tagsView: {
|
||||||
refresh: 'refresh',
|
refresh: 'refresh',
|
||||||
|
@ -105,7 +105,6 @@ export default {
|
|||||||
logOutConfirm: '确定',
|
logOutConfirm: '确定',
|
||||||
logOutCancel: '取消',
|
logOutCancel: '取消',
|
||||||
logOutExit: '退出中',
|
logOutExit: '退出中',
|
||||||
logOutSuccess: '安全退出成功!',
|
|
||||||
},
|
},
|
||||||
tagsView: {
|
tagsView: {
|
||||||
refresh: '刷新',
|
refresh: '刷新',
|
||||||
|
@ -105,7 +105,6 @@ export default {
|
|||||||
logOutConfirm: '確定',
|
logOutConfirm: '確定',
|
||||||
logOutCancel: '取消',
|
logOutCancel: '取消',
|
||||||
logOutExit: '退出中',
|
logOutExit: '退出中',
|
||||||
logOutSuccess: '安全退出成功!',
|
|
||||||
},
|
},
|
||||||
tagsView: {
|
tagsView: {
|
||||||
refresh: '重繪',
|
refresh: '重繪',
|
||||||
|
@ -82,7 +82,6 @@ import { useRouter } from 'vue-router';
|
|||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
import screenfull from 'screenfull';
|
import screenfull from 'screenfull';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { resetRoute } from '/@/router/index';
|
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useUserInfo } from '/@/stores/userInfo';
|
import { useUserInfo } from '/@/stores/userInfo';
|
||||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
import { useThemeConfig } from '/@/stores/themeConfig';
|
||||||
@ -162,8 +161,7 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
Session.clear(); // 清除缓存/token等
|
Session.clear(); // 清除缓存/token等
|
||||||
await resetRoute(); // 删除/重置路由
|
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
||||||
ElMessage.success(t('message.user.logOutSuccess'));
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
|
@ -1,15 +1,23 @@
|
|||||||
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import pinia from '/@/stores/index';
|
||||||
import { useUserInfo } from '/@/stores/userInfo';
|
import { useUserInfo } from '/@/stores/userInfo';
|
||||||
import { useRequestOldRoutes } from '/@/stores/requestOldRoutes';
|
import { useRequestOldRoutes } from '/@/stores/requestOldRoutes';
|
||||||
import { Session } from '/@/utils/storage';
|
import { Session } from '/@/utils/storage';
|
||||||
import { NextLoading } from '/@/utils/loading';
|
import { NextLoading } from '/@/utils/loading';
|
||||||
import { setAddRoute, setFilterMenuAndCacheTagsViewRoutes } from '/@/router/index';
|
import { dynamicRoutes, notFoundAndNoPower } from '/@/router/route';
|
||||||
import { dynamicRoutes } from '/@/router/route';
|
import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '/@/router/index';
|
||||||
|
import { useRoutesList } from '/@/stores/routesList';
|
||||||
|
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
|
||||||
import { useMenuApi } from '/@/api/menu/index';
|
import { useMenuApi } from '/@/api/menu/index';
|
||||||
|
|
||||||
const menuApi = useMenuApi();
|
const menuApi = useMenuApi();
|
||||||
|
|
||||||
const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}');
|
const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}');
|
||||||
const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}');
|
const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}');
|
||||||
|
|
||||||
|
// 后端控制路由
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取目录下的 .vue、.tsx 全部文件
|
* 获取目录下的 .vue、.tsx 全部文件
|
||||||
* @method import.meta.glob
|
* @method import.meta.glob
|
||||||
@ -21,7 +29,7 @@ const dynamicViewsModules: Record<string, Function> = Object.assign({}, { ...lay
|
|||||||
* 后端控制路由:初始化方法,防止刷新时路由丢失
|
* 后端控制路由:初始化方法,防止刷新时路由丢失
|
||||||
* @method NextLoading 界面 loading 动画开始执行
|
* @method NextLoading 界面 loading 动画开始执行
|
||||||
* @method useUserInfo().setUserInfos() 触发初始化用户信息 pinia
|
* @method useUserInfo().setUserInfos() 触发初始化用户信息 pinia
|
||||||
* @method useRequestOldRoutes().setCacheKeepAlive() 存储接口原始路由(未处理component),根据需求选择使用
|
* @method useRequestOldRoutes().setRequestOldRoutes() 存储接口原始路由(未处理component),根据需求选择使用
|
||||||
* @method setAddRoute 添加动态路由
|
* @method setAddRoute 添加动态路由
|
||||||
* @method setFilterMenuAndCacheTagsViewRoutes 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
* @method setFilterMenuAndCacheTagsViewRoutes 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||||
*/
|
*/
|
||||||
@ -36,13 +44,59 @@ export async function initBackEndControlRoutes() {
|
|||||||
// 获取路由菜单数据
|
// 获取路由菜单数据
|
||||||
const res = await getBackEndControlRoutes();
|
const res = await getBackEndControlRoutes();
|
||||||
// 存储接口原始路由(未处理component),根据需求选择使用
|
// 存储接口原始路由(未处理component),根据需求选择使用
|
||||||
useRequestOldRoutes().setCacheKeepAlive(JSON.parse(JSON.stringify(res.data)));
|
useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data)));
|
||||||
// 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
// 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
||||||
dynamicRoutes[0].children = await backEndComponent(res.data);
|
dynamicRoutes[0].children = await backEndComponent(res.data);
|
||||||
// 添加动态路由
|
// 添加动态路由
|
||||||
await setAddRoute();
|
await setAddRoute();
|
||||||
// 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
// // 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||||
setFilterMenuAndCacheTagsViewRoutes();
|
await setFilterMenuAndCacheTagsViewRoutes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||||
|
* @description 用于左侧菜单、横向菜单的显示
|
||||||
|
* @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide)
|
||||||
|
*/
|
||||||
|
export function setFilterMenuAndCacheTagsViewRoutes() {
|
||||||
|
const storesRoutesList = useRoutesList(pinia);
|
||||||
|
storesRoutesList.setRoutesList(dynamicRoutes[0].children as any);
|
||||||
|
setCacheTagsViewRoutes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存多级嵌套数组处理后的一维数组
|
||||||
|
* @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide)
|
||||||
|
*/
|
||||||
|
export function setCacheTagsViewRoutes() {
|
||||||
|
// 获取有权限的路由,否则 tagsView、菜单搜索中无权限的路由也将显示
|
||||||
|
const storesTagsView = useTagsViewRoutes(pinia);
|
||||||
|
// 添加到 pinia setTagsViewRoutes 中
|
||||||
|
storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes))[0].children);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取有当前用户权限标识的路由数组,进行对原路由的替换
|
||||||
|
* @description 替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
||||||
|
* @returns 返回替换后的路由数组
|
||||||
|
*/
|
||||||
|
export function setFilterRouteEnd() {
|
||||||
|
// console.log(dynamicRoutes);
|
||||||
|
let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));
|
||||||
|
filterRouteEnd[0].children = [...filterRouteEnd[0].children, ...notFoundAndNoPower];
|
||||||
|
return filterRouteEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加动态路由
|
||||||
|
* @method router.addRoute
|
||||||
|
* @description 此处循环为 dynamicRoutes(/@/router/route)第一个顶级 children 的路由一维数组,非多级嵌套
|
||||||
|
* @link 参考:https://next.router.vuejs.org/zh/api/#addroute
|
||||||
|
*/
|
||||||
|
export async function setAddRoute() {
|
||||||
|
await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
|
||||||
|
router.addRoute(route);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,8 +106,9 @@ export async function initBackEndControlRoutes() {
|
|||||||
*/
|
*/
|
||||||
export function getBackEndControlRoutes() {
|
export function getBackEndControlRoutes() {
|
||||||
// 模拟 admin 与 test
|
// 模拟 admin 与 test
|
||||||
const stores = useUserInfo();
|
const stores = useUserInfo(pinia);
|
||||||
const auth = stores.userInfos.roles[0];
|
const { userInfos } = storeToRefs(stores);
|
||||||
|
const auth = userInfos.value.roles[0];
|
||||||
// 管理员 admin
|
// 管理员 admin
|
||||||
if (auth === 'admin') return menuApi.getMenuAdmin();
|
if (auth === 'admin') return menuApi.getMenuAdmin();
|
||||||
// 其它用户 test
|
// 其它用户 test
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '/@/router/index';
|
||||||
|
import { dynamicRoutes, notFoundAndNoPower } from '/@/router/route';
|
||||||
import pinia from '/@/stores/index';
|
import pinia from '/@/stores/index';
|
||||||
import { useUserInfo } from '/@/stores/userInfo';
|
|
||||||
import { Session } from '/@/utils/storage';
|
import { Session } from '/@/utils/storage';
|
||||||
|
import { useUserInfo } from '/@/stores/userInfo';
|
||||||
|
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
|
||||||
|
import { useRoutesList } from '/@/stores/routesList';
|
||||||
import { NextLoading } from '/@/utils/loading';
|
import { NextLoading } from '/@/utils/loading';
|
||||||
import { setAddRoute, setFilterMenuAndCacheTagsViewRoutes } from '/@/router/index';
|
|
||||||
|
// 前端控制路由
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 前端控制路由:初始化方法,防止刷新时路由丢失
|
* 前端控制路由:初始化方法,防止刷新时路由丢失
|
||||||
@ -23,3 +30,118 @@ export async function initFrontEndControlRoutes() {
|
|||||||
// 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
// 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||||
await setFilterMenuAndCacheTagsViewRoutes();
|
await setFilterMenuAndCacheTagsViewRoutes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加动态路由
|
||||||
|
* @method router.addRoute
|
||||||
|
* @description 此处循环为 dynamicRoutes(/@/router/route)第一个顶级 children 的路由一维数组,非多级嵌套
|
||||||
|
* @link 参考:https://next.router.vuejs.org/zh/api/#addroute
|
||||||
|
*/
|
||||||
|
export async function setAddRoute() {
|
||||||
|
await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
|
||||||
|
router.addRoute(route);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除/重置路由
|
||||||
|
* @method router.removeRoute
|
||||||
|
* @description 此处循环为 dynamicRoutes(/@/router/route)第一个顶级 children 的路由一维数组,非多级嵌套
|
||||||
|
* @link 参考:https://next.router.vuejs.org/zh/api/#push
|
||||||
|
*/
|
||||||
|
export async function frontEndsResetRoute() {
|
||||||
|
await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
|
||||||
|
const routeName: any = route.name;
|
||||||
|
router.hasRoute(routeName) && router.removeRoute(routeName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取有当前用户权限标识的路由数组,进行对原路由的替换
|
||||||
|
* @description 替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
||||||
|
* @returns 返回替换后的路由数组
|
||||||
|
*/
|
||||||
|
export function setFilterRouteEnd() {
|
||||||
|
let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));
|
||||||
|
filterRouteEnd[0].children = [...setFilterRoute(filterRouteEnd[0].children), ...notFoundAndNoPower];
|
||||||
|
return filterRouteEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前用户权限标识去比对路由表(未处理成多级嵌套路由)
|
||||||
|
* @description 这里主要用于动态路由的添加,router.addRoute
|
||||||
|
* @link 参考:https://next.router.vuejs.org/zh/api/#addroute
|
||||||
|
* @param chil dynamicRoutes(/@/router/route)第一个顶级 children 的下路由集合
|
||||||
|
* @returns 返回有当前用户权限标识的路由数组
|
||||||
|
*/
|
||||||
|
export function setFilterRoute(chil: any) {
|
||||||
|
const stores = useUserInfo(pinia);
|
||||||
|
const { userInfos } = storeToRefs(stores);
|
||||||
|
let filterRoute: any = [];
|
||||||
|
chil.forEach((route: any) => {
|
||||||
|
if (route.meta.roles) {
|
||||||
|
route.meta.roles.forEach((metaRoles: any) => {
|
||||||
|
userInfos.value.roles.forEach((roles: any) => {
|
||||||
|
if (metaRoles === roles) filterRoute.push({ ...route });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return filterRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存多级嵌套数组处理后的一维数组
|
||||||
|
* @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide)
|
||||||
|
*/
|
||||||
|
export function setCacheTagsViewRoutes() {
|
||||||
|
// 获取有权限的路由,否则 tagsView、菜单搜索中无权限的路由也将显示
|
||||||
|
const stores = useUserInfo(pinia);
|
||||||
|
const storesTagsView = useTagsViewRoutes(pinia);
|
||||||
|
const { userInfos } = storeToRefs(stores);
|
||||||
|
let rolesRoutes = setFilterHasRolesMenu(dynamicRoutes, userInfos.value.roles);
|
||||||
|
// 添加到 pinia setTagsViewRoutes 中
|
||||||
|
storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(rolesRoutes))[0].children);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||||
|
* @description 用于左侧菜单、横向菜单的显示
|
||||||
|
* @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide)
|
||||||
|
*/
|
||||||
|
export function setFilterMenuAndCacheTagsViewRoutes() {
|
||||||
|
const stores = useUserInfo(pinia);
|
||||||
|
const storesRoutesList = useRoutesList(pinia);
|
||||||
|
const { userInfos } = storeToRefs(stores);
|
||||||
|
storesRoutesList.setRoutesList(setFilterHasRolesMenu(dynamicRoutes[0].children, userInfos.value.roles));
|
||||||
|
setCacheTagsViewRoutes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断路由 `meta.roles` 中是否包含当前登录用户权限字段
|
||||||
|
* @param roles 用户权限标识,在 userInfos(用户信息)的 roles(登录页登录时缓存到浏览器)数组
|
||||||
|
* @param route 当前循环时的路由项
|
||||||
|
* @returns 返回对比后有权限的路由项
|
||||||
|
*/
|
||||||
|
export function hasRoles(roles: any, route: any) {
|
||||||
|
if (route.meta && route.meta.roles) return roles.some((role: any) => route.meta.roles.includes(role));
|
||||||
|
else return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前用户权限标识去比对路由表,设置递归过滤有权限的路由
|
||||||
|
* @param routes 当前路由 children
|
||||||
|
* @param roles 用户权限标识,在 userInfos(用户信息)的 roles(登录页登录时缓存到浏览器)数组
|
||||||
|
* @returns 返回有权限的路由数组 `meta.roles` 中控制
|
||||||
|
*/
|
||||||
|
export function setFilterHasRolesMenu(routes: any, roles: any) {
|
||||||
|
const menu: any = [];
|
||||||
|
routes.forEach((route: any) => {
|
||||||
|
const item = { ...route };
|
||||||
|
if (hasRoles(roles, item)) {
|
||||||
|
if (item.children) item.children = setFilterHasRolesMenu(item.children, roles);
|
||||||
|
menu.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
@ -1,53 +1,41 @@
|
|||||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
|
import { createRouter, createWebHashHistory } from 'vue-router';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
import pinia from '/@/stores/index';
|
import pinia from '/@/stores/index';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useUserInfo } from '/@/stores/userInfo';
|
|
||||||
import { useKeepALiveNames } from '/@/stores/keepAliveNames';
|
import { useKeepALiveNames } from '/@/stores/keepAliveNames';
|
||||||
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
|
|
||||||
import { useRoutesList } from '/@/stores/routesList';
|
import { useRoutesList } from '/@/stores/routesList';
|
||||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
import { useThemeConfig } from '/@/stores/themeConfig';
|
||||||
import { Session } from '/@/utils/storage';
|
import { Session } from '/@/utils/storage';
|
||||||
import { staticRoutes, dynamicRoutes } from '/@/router/route';
|
import { staticRoutes } from '/@/router/route';
|
||||||
import { initFrontEndControlRoutes } from '/@/router/frontEnd';
|
import { initFrontEndControlRoutes } from '/@/router/frontEnd';
|
||||||
import { initBackEndControlRoutes } from '/@/router/backEnd';
|
import { initBackEndControlRoutes } from '/@/router/backEnd';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1、前端控制路由时:isRequestRoutes 为 false,需要写 roles,需要走 setFilterRoute 方法。
|
||||||
|
* 2、后端控制路由时:isRequestRoutes 为 true,不需要写 roles,不需要走 setFilterRoute 方法),
|
||||||
|
* 相关方法已拆解到对应的 `backEnd.ts` 与 `frontEnd.ts`(他们互不影响,不需要同时改 2 个文件)。
|
||||||
|
* 特别说明:
|
||||||
|
* 1、前端控制:路由菜单由前端去写(无菜单管理界面,有角色管理界面),角色管理中有 roles 属性,需返回到 userInfo 中。
|
||||||
|
* 2、后端控制:路由菜单由后端返回(有菜单管理界面、有角色管理界面)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 读取 `/src/stores/themeConfig.ts` 是否开启后端控制路由配置
|
||||||
|
const storesThemeConfig = useThemeConfig(pinia);
|
||||||
|
const { themeConfig } = storeToRefs(storesThemeConfig);
|
||||||
|
const { isRequestRoutes } = themeConfig.value;
|
||||||
|
if (isRequestRoutes) staticRoutes.splice(0, 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个可以被 Vue 应用程序使用的路由实例
|
* 创建一个可以被 Vue 应用程序使用的路由实例
|
||||||
* @method createRouter(options: RouterOptions): Router
|
* @method createRouter(options: RouterOptions): Router
|
||||||
* @link 参考:https://next.router.vuejs.org/zh/api/#createrouter
|
* @link 参考:https://next.router.vuejs.org/zh/api/#createrouter
|
||||||
*/
|
*/
|
||||||
const router = createRouter({
|
export const router = createRouter({
|
||||||
history: createWebHashHistory(),
|
history: createWebHashHistory(),
|
||||||
routes: staticRoutes,
|
routes: staticRoutes,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* 定义404、401界面
|
|
||||||
* @link 参考:https://next.router.vuejs.org/zh/guide/essentials/history-mode.html#netlify
|
|
||||||
*/
|
|
||||||
const notFoundAndNoPower = [
|
|
||||||
{
|
|
||||||
path: '/:path(.*)*',
|
|
||||||
name: 'notFound',
|
|
||||||
component: () => import('/@/views/error/404.vue'),
|
|
||||||
meta: {
|
|
||||||
title: 'message.staticRoutes.notFound',
|
|
||||||
isHide: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/401',
|
|
||||||
name: 'noPower',
|
|
||||||
component: () => import('/@/views/error/401.vue'),
|
|
||||||
meta: {
|
|
||||||
title: 'message.staticRoutes.noPower',
|
|
||||||
isHide: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 路由多级嵌套数组处理成一维数组
|
* 路由多级嵌套数组处理成一维数组
|
||||||
* @param arr 传入路由菜单数据数组
|
* @param arr 传入路由菜单数据数组
|
||||||
@ -97,127 +85,7 @@ export function formatTwoStageRoutes(arr: any) {
|
|||||||
return newArr;
|
return newArr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存多级嵌套数组处理后的一维数组
|
|
||||||
* @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide)
|
|
||||||
*/
|
|
||||||
export function setCacheTagsViewRoutes() {
|
|
||||||
// 获取有权限的路由,否则 tagsView、菜单搜索中无权限的路由也将显示
|
|
||||||
const stores = useUserInfo(pinia);
|
|
||||||
const storesTagsView = useTagsViewRoutes(pinia);
|
|
||||||
const { userInfos } = storeToRefs(stores);
|
|
||||||
let rolesRoutes = setFilterHasRolesMenu(dynamicRoutes, userInfos.value.roles);
|
|
||||||
// 添加到 pinia setTagsViewRoutes 中
|
|
||||||
storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(rolesRoutes))[0].children);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断路由 `meta.roles` 中是否包含当前登录用户权限字段
|
|
||||||
* @param roles 用户权限标识,在 userInfos(用户信息)的 roles(登录页登录时缓存到浏览器)数组
|
|
||||||
* @param route 当前循环时的路由项
|
|
||||||
* @returns 返回对比后有权限的路由项
|
|
||||||
*/
|
|
||||||
export function hasRoles(roles: any, route: any) {
|
|
||||||
if (route.meta && route.meta.roles) return roles.some((role: any) => route.meta.roles.includes(role));
|
|
||||||
else return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前用户权限标识去比对路由表,设置递归过滤有权限的路由
|
|
||||||
* @param routes 当前路由 children
|
|
||||||
* @param roles 用户权限标识,在 userInfos(用户信息)的 roles(登录页登录时缓存到浏览器)数组
|
|
||||||
* @returns 返回有权限的路由数组 `meta.roles` 中控制
|
|
||||||
*/
|
|
||||||
export function setFilterHasRolesMenu(routes: any, roles: any) {
|
|
||||||
const menu: any = [];
|
|
||||||
routes.forEach((route: any) => {
|
|
||||||
const item = { ...route };
|
|
||||||
if (hasRoles(roles, item)) {
|
|
||||||
if (item.children) item.children = setFilterHasRolesMenu(item.children, roles);
|
|
||||||
menu.push(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
|
||||||
* @description 用于左侧菜单、横向菜单的显示
|
|
||||||
* @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide)
|
|
||||||
*/
|
|
||||||
export function setFilterMenuAndCacheTagsViewRoutes() {
|
|
||||||
const stores = useUserInfo(pinia);
|
|
||||||
const storesRoutesList = useRoutesList(pinia);
|
|
||||||
const { userInfos } = storeToRefs(stores);
|
|
||||||
storesRoutesList.setRoutesList(setFilterHasRolesMenu(dynamicRoutes[0].children, userInfos.value.roles));
|
|
||||||
setCacheTagsViewRoutes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前用户权限标识去比对路由表(未处理成多级嵌套路由)
|
|
||||||
* @description 这里主要用于动态路由的添加,router.addRoute
|
|
||||||
* @link 参考:https://next.router.vuejs.org/zh/api/#addroute
|
|
||||||
* @param chil dynamicRoutes(/@/router/route)第一个顶级 children 的下路由集合
|
|
||||||
* @returns 返回有当前用户权限标识的路由数组
|
|
||||||
*/
|
|
||||||
export function setFilterRoute(chil: any) {
|
|
||||||
const stores = useUserInfo(pinia);
|
|
||||||
const { userInfos } = storeToRefs(stores);
|
|
||||||
let filterRoute: any = [];
|
|
||||||
chil.forEach((route: any) => {
|
|
||||||
if (route.meta.roles) {
|
|
||||||
route.meta.roles.forEach((metaRoles: any) => {
|
|
||||||
userInfos.value.roles.forEach((roles: any) => {
|
|
||||||
if (metaRoles === roles) filterRoute.push({ ...route });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return filterRoute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取有当前用户权限标识的路由数组,进行对原路由的替换
|
|
||||||
* @description 替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
|
||||||
* @returns 返回替换后的路由数组
|
|
||||||
*/
|
|
||||||
export function setFilterRouteEnd() {
|
|
||||||
let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));
|
|
||||||
filterRouteEnd[0].children = [...setFilterRoute(filterRouteEnd[0].children), ...notFoundAndNoPower];
|
|
||||||
return filterRouteEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加动态路由
|
|
||||||
* @method router.addRoute
|
|
||||||
* @description 此处循环为 dynamicRoutes(/@/router/route)第一个顶级 children 的路由一维数组,非多级嵌套
|
|
||||||
* @link 参考:https://next.router.vuejs.org/zh/api/#addroute
|
|
||||||
*/
|
|
||||||
export async function setAddRoute() {
|
|
||||||
await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
|
|
||||||
const routeName: any = route.name;
|
|
||||||
if (!router.hasRoute(routeName)) router.addRoute(route);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除/重置路由
|
|
||||||
* @method router.removeRoute
|
|
||||||
* @description 此处循环为 dynamicRoutes(/@/router/route)第一个顶级 children 的路由一维数组,非多级嵌套
|
|
||||||
* @link 参考:https://next.router.vuejs.org/zh/api/#push
|
|
||||||
*/
|
|
||||||
export async function resetRoute() {
|
|
||||||
await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
|
|
||||||
const routeName: any = route.name;
|
|
||||||
router.hasRoute(routeName) && router.removeRoute(routeName);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// isRequestRoutes 为 true,则开启后端控制路由,路径:`/src/stores/themeConfig.ts`
|
// isRequestRoutes 为 true,则开启后端控制路由,路径:`/src/stores/themeConfig.ts`
|
||||||
const storesThemeConfig = useThemeConfig(pinia);
|
|
||||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
|
||||||
const { isRequestRoutes } = themeConfig.value;
|
|
||||||
// 前端控制路由:初始化方法,防止刷新时路由丢失
|
|
||||||
if (!isRequestRoutes) initFrontEndControlRoutes();
|
if (!isRequestRoutes) initFrontEndControlRoutes();
|
||||||
|
|
||||||
// 路由加载前
|
// 路由加载前
|
||||||
@ -232,7 +100,6 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
if (!token) {
|
if (!token) {
|
||||||
next(`/login?redirect=${to.path}¶ms=${JSON.stringify(to.query ? to.query : to.params)}`);
|
next(`/login?redirect=${to.path}¶ms=${JSON.stringify(to.query ? to.query : to.params)}`);
|
||||||
Session.clear();
|
Session.clear();
|
||||||
resetRoute();
|
|
||||||
NProgress.done();
|
NProgress.done();
|
||||||
} else if (token && to.path === '/login') {
|
} else if (token && to.path === '/login') {
|
||||||
next('/home');
|
next('/home');
|
||||||
|
@ -16,6 +16,7 @@ import { RouteRecordRaw } from 'vue-router';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 定义动态路由
|
* 定义动态路由
|
||||||
|
* 前端添加路由,请在顶级节点的 `children 数组` 里添加
|
||||||
* @description 未开启 isRequestRoutes 为 true 时使用(前端控制路由),开启时第一个顶级 children 的路由将被替换成接口请求回来的路由数据
|
* @description 未开启 isRequestRoutes 为 true 时使用(前端控制路由),开启时第一个顶级 children 的路由将被替换成接口请求回来的路由数据
|
||||||
* @description 各字段请查看 `/@/views/system/menu/component/addMenu.vue 下的 ruleForm`
|
* @description 各字段请查看 `/@/views/system/menu/component/addMenu.vue 下的 ruleForm`
|
||||||
* @returns 返回路由菜单数据
|
* @returns 返回路由菜单数据
|
||||||
@ -1132,11 +1133,49 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定义静态路由
|
* 定义404、401界面
|
||||||
|
* @link 参考:https://next.router.vuejs.org/zh/guide/essentials/history-mode.html#netlify
|
||||||
|
*/
|
||||||
|
export const notFoundAndNoPower = [
|
||||||
|
{
|
||||||
|
path: '/:path(.*)*',
|
||||||
|
name: 'notFound',
|
||||||
|
component: () => import('/@/views/error/404.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'message.staticRoutes.notFound',
|
||||||
|
isHide: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/401',
|
||||||
|
name: 'noPower',
|
||||||
|
component: () => import('/@/views/error/401.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'message.staticRoutes.noPower',
|
||||||
|
isHide: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义静态路由(默认路由)
|
||||||
|
* 此路由不要动,前端添加路由的话,请在 `dynamicRoutes 数组` 中添加
|
||||||
* @description 前端控制直接改 dynamicRoutes 中的路由,后端控制不需要修改,请求接口路由数据时,会覆盖 dynamicRoutes 第一个顶级 children 的内容(全屏,不包含 layout 中的路由出口)
|
* @description 前端控制直接改 dynamicRoutes 中的路由,后端控制不需要修改,请求接口路由数据时,会覆盖 dynamicRoutes 第一个顶级 children 的内容(全屏,不包含 layout 中的路由出口)
|
||||||
* @returns 返回路由菜单数据
|
* @returns 返回路由菜单数据
|
||||||
*/
|
*/
|
||||||
export const staticRoutes: Array<RouteRecordRaw> = [
|
export const staticRoutes: Array<RouteRecordRaw> = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: '/',
|
||||||
|
component: () => import('/@/layout/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '布局界面',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
// 请不要往这里 `children` 中添加内容,此内容为了防止 No match found for location with path "xxx" 问题
|
||||||
|
...notFoundAndNoPower,
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
name: 'login',
|
name: 'login',
|
||||||
|
@ -10,7 +10,7 @@ export const useRequestOldRoutes = defineStore('requestOldRoutes', {
|
|||||||
requestOldRoutes: [],
|
requestOldRoutes: [],
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
async setCacheKeepAlive(routes: Array<string>) {
|
async setRequestOldRoutes(routes: Array<string>) {
|
||||||
this.requestOldRoutes = routes;
|
this.requestOldRoutes = routes;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -33,3 +33,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 页面宽度小于1200px
|
||||||
|
------------------------------- */
|
||||||
|
@media screen and (max-width: $lg) {
|
||||||
|
.error {
|
||||||
|
.error-flex {
|
||||||
|
padding: 0 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 文本不换行
|
/* 文本不换行
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
import { toRefs, reactive, onMounted, defineComponent } from 'vue';
|
import { toRefs, reactive, onMounted, defineComponent } from 'vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useUserInfo } from '/@/stores/userInfo';
|
import { useUserInfo } from '/@/stores/userInfo';
|
||||||
import { resetRoute, setAddRoute, setFilterMenuAndCacheTagsViewRoutes } from '/@/router/index';
|
import { frontEndsResetRoute, setAddRoute, setFilterMenuAndCacheTagsViewRoutes } from '/@/router/frontEnd';
|
||||||
import { Session } from '/@/utils/storage';
|
import { Session } from '/@/utils/storage';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@ -45,7 +45,7 @@ export default defineComponent({
|
|||||||
// 用户权限改变时
|
// 用户权限改变时
|
||||||
const onRadioChange = async () => {
|
const onRadioChange = async () => {
|
||||||
// 模拟数据
|
// 模拟数据
|
||||||
resetRoute();
|
frontEndsResetRoute();
|
||||||
let defaultRoles: string[] = [];
|
let defaultRoles: string[] = [];
|
||||||
let defaultAuthBtnList: string[] = [];
|
let defaultAuthBtnList: string[] = [];
|
||||||
// admin 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
|
// admin 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
|
||||||
|
@ -93,6 +93,7 @@ import { toRefs, reactive, onMounted, onUnmounted, getCurrentInstance, defineCom
|
|||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import 'echarts/extension/bmap/bmap';
|
import 'echarts/extension/bmap/bmap';
|
||||||
import { formatDate } from '/@/utils/formatTime';
|
import { formatDate } from '/@/utils/formatTime';
|
||||||
|
import { NextLoading } from '/@/utils/loading';
|
||||||
import { echartsMapList, echartsMapData, echartsMapImgs } from './mock/demo1';
|
import { echartsMapList, echartsMapData, echartsMapImgs } from './mock/demo1';
|
||||||
|
|
||||||
// 定义接口来定义对象的类型
|
// 定义接口来定义对象的类型
|
||||||
@ -934,6 +935,7 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
// 页面加载时
|
// 页面加载时
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
NextLoading.done();
|
||||||
initTime();
|
initTime();
|
||||||
await initEchartsMap();
|
await initEchartsMap();
|
||||||
await initVisualizingContentLeftTop();
|
await initVisualizingContentLeftTop();
|
||||||
|
@ -233,6 +233,7 @@ import { toRefs, reactive, onMounted, onUnmounted, getCurrentInstance, defineCom
|
|||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import 'echarts-gl';
|
import 'echarts-gl';
|
||||||
import { formatDate } from '/@/utils/formatTime';
|
import { formatDate } from '/@/utils/formatTime';
|
||||||
|
import { NextLoading } from '/@/utils/loading';
|
||||||
import { dropdownList, skyList, dBtnList, earth3DBtnList, chartData4List } from './mock/demo2';
|
import { dropdownList, skyList, dBtnList, earth3DBtnList, chartData4List } from './mock/demo2';
|
||||||
import worldImg from './images/world.jpg';
|
import worldImg from './images/world.jpg';
|
||||||
import bathymetryImg from './images/bathymetry.jpg';
|
import bathymetryImg from './images/bathymetry.jpg';
|
||||||
@ -765,6 +766,7 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
// 页面加载时
|
// 页面加载时
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
NextLoading.done();
|
||||||
initTime();
|
initTime();
|
||||||
await initRightChartData1();
|
await initRightChartData1();
|
||||||
await initRightChartData4();
|
await initRightChartData4();
|
||||||
|
Loading…
Reference in New Issue
Block a user