feat(preoject): 增加页面缓存支持,外链菜单支持

This commit is contained in:
Coffee-crocodile 2022-10-17 18:10:16 +08:00
parent d0d6a59491
commit af8ceb0843
25 changed files with 56 additions and 28 deletions

View File

@ -183,6 +183,7 @@ const userRoutes = [
title: '地图',
requiresAuth: true,
icon: 'carbon:map',
keepAlive: true,
},
},
{
@ -271,6 +272,16 @@ const userRoutes = [
icon: 'logos:vitejs',
},
},
{
name: 'docments_vueuse',
path: '/docments/vueuse',
meta: {
title: 'VueUse外链',
requiresAuth: true,
icon: 'logos:vueuse',
herf: 'https://vueuse.org/guide/',
},
},
],
},
{

View File

@ -8,7 +8,7 @@
</template>
<script setup lang="ts">
import { useAppRouter } from '@/hook';
import { useAppRouter } from '@/hooks';
type TipType = '403' | '404' | '500';
defineProps<{

View File

@ -52,9 +52,11 @@
'p-t-77px': appStore.fixedHeader && !appStore.showTabs,
}"
>
<router-view v-slot="{ Component }">
<transition name="fade-slide" appear mode="out-in">
<component :is="Component" v-if="appStore.loadFlag" />
<router-view v-slot="{ Component, route }">
<transition name="fade-slide" mode="out-in">
<keep-alive :include="routeStore.cacheRoutes">
<component :is="Component" v-if="appStore.loadFlag" :key="route.fullPath" />
</keep-alive>
</transition>
</router-view>
</div>
@ -68,7 +70,6 @@
</template>
<script lang="ts" setup>
import { useAppStore } from '@/store';
import {
Breadcrumb,
CollapaseButton,
@ -85,7 +86,9 @@ import {
TabBar,
BackTop,
} from '../components';
import { useAppStore, useRouteStore } from '@/store';
const routeStore = useRouteStore();
const appStore = useAppStore();
</script>

View File

@ -11,7 +11,7 @@
import { computed } from 'vue';
import { useRouter } from 'vue-router';
import { useRouteStore } from '@/store';
import { useAppRouter } from '@/hook';
import { useAppRouter } from '@/hooks';
const router = useRouter();
const routeStore = useRouteStore();

View File

@ -7,7 +7,7 @@
<script setup lang="ts">
import { useAppStore } from '@/store';
import { useAppRouter } from '@/hook';
import { useAppRouter } from '@/hooks';
const { toRoot } = useAppRouter();
const appStore = useAppStore();
</script>

View File

@ -13,7 +13,7 @@
<script setup lang="ts">
import { useAppStore } from '@/store';
import { useAppRouter } from '@/hook';
import { useAppRouter } from '@/hooks';
import { useRouteStore } from '~/src/store/modules/route';
import type { MenuOption } from 'naive-ui';

View File

@ -30,7 +30,7 @@
<script setup lang="ts">
import { useTabStore, useAppStore } from '@/store';
import { useAppRouter } from '~/src/hook';
import { useAppRouter } from '@/hooks';
import { RouteLocationNormalized } from 'vue-router';
import { ref, nextTick } from 'vue';
import { renderIcon } from '@/utils';

View File

@ -1,5 +1,6 @@
import { RouteRecordRaw } from 'vue-router';
import { BasicLayout } from '@/layouts/index';
import { useRouteStore } from '@/store';
// 引入所有页面
const modules = import.meta.glob('../../views/**/*.vue');
@ -20,9 +21,20 @@ function FlatAuthRoutes(routes: AppRoute.Route[]) {
});
return result;
}
function createCatheRoutes(routes: AppRoute.Route[]) {
return routes
.filter((item) => {
return item.meta.keepAlive;
})
.map((item) => item.name);
}
export async function createDynamicRoutes(routes: AppRoute.Route[]) {
// 数组降维成一维数组,然后删除所有的childen
const flatRoutes = FlatAuthRoutes(routes);
// 对降维后的数组过滤需要缓存的路由name数组
const routeStore = useRouteStore();
routeStore.cacheRoutes = createCatheRoutes(flatRoutes);
// 生成路由有redirect的不需要引入文件
const mapRoutes = flatRoutes.map((item) => {
if (!item.redirect) {

View File

@ -6,6 +6,11 @@ const appTitle = import.meta.env.VITE_APP_TITLE;
export function setupRouterGuard(router: Router) {
router.beforeEach(async (to, from, next) => {
// 判断是否是外链,如果是直接打开网页并拦截跳转
if (to.meta.herf) {
window.open(to.meta.herf);
return false;
}
// 开始 loadingBar
window.$loadingBar?.start();
// 权限操作

View File

@ -40,7 +40,6 @@ export async function createPermissionGuard(
// if (to.name === 'not-found-page') {
// next({ name: 'not-found-page', replace: true });
// }
// 设置菜单高亮
if (to.meta.activeMenu) {
routeStore.setActiveMenu(to.meta.activeMenu);

View File

@ -2,7 +2,7 @@ import { defineStore } from 'pinia';
import { fetchLogin, fetchUserInfo } from '@/service';
import { setUserInfo, getUserInfo, getToken, setToken, clearAuthStorage } from '@/utils/auth';
import { router } from '@/router';
import { useAppRouter } from '@/hook';
import { useAppRouter } from '@/hooks';
import { unref } from 'vue';
import { useRouteStore } from './route';

View File

@ -12,6 +12,7 @@ interface RoutesStatus {
userRoutes: AppRoute.Route[];
activeMenu: string | null;
authRouteMode: ImportMetaEnv['VITE_AUTH_ROUTE_MODE'];
cacheRoutes: string[];
}
export const useRouteStore = defineStore('route-store', {
state: (): RoutesStatus => {
@ -21,6 +22,7 @@ export const useRouteStore = defineStore('route-store', {
menus: [],
activeMenu: null,
authRouteMode: import.meta.env.VITE_AUTH_ROUTE_MODE,
cacheRoutes: [],
};
},
actions: {
@ -81,7 +83,7 @@ export const useRouteStore = defineStore('route-store', {
const { data } = await fetchUserRoutes(userId);
// 根据用户返回的路由表来生成真实路由
const appRoutes = await createDynamicRoutes(data);
// 更具返回的生成侧边菜单
// 生成侧边菜单
await this.createMenus(data);
// 插入路由表
router.addRoute(appRoutes);
@ -90,7 +92,7 @@ export const useRouteStore = defineStore('route-store', {
async initStaticRoute() {
// 根据静态路由表来生成真实路由
const appRoutes = await createDynamicRoutes(staticRoutes);
// 更具返回的生成侧边菜单
// 生成侧边菜单
await this.createMenus(staticRoutes);
// 插入路由表
router.addRoute(appRoutes);

View File

@ -1,6 +1,6 @@
import { defineStore } from 'pinia';
import { RouteLocationNormalized } from 'vue-router';
import { useAppRouter } from '@/hook';
import { useAppRouter } from '@/hooks';
interface TabState {
inherentTab: {

View File

@ -7,14 +7,6 @@ declare namespace AppRoute {
path: string;
/** 路由重定向 */
redirect?: string;
/**
*
* - basic: 基础布局
* - blank: 空白布局
* - multi: 多级路由布局()
* - self: 作为子路由使()
*/
component?: any;
/** 子路由 */
children?: Route[];
/** 路由描述 */

View File

@ -59,7 +59,7 @@ import { onMounted, ref, h } from 'vue';
import { fetchUserList } from '@/service';
import type { DataTableColumns } from 'naive-ui';
import { NButton, NPopconfirm, NSpace, NSwitch, NTag, FormInst } from 'naive-ui';
import { useLoading, useBoolean } from '@/hook';
import { useLoading, useBoolean } from '@/hooks';
import TableModal from './components/TableModal.vue';
const { loading, startLoading, endLoading } = useLoading(false);

View File

@ -12,7 +12,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import type { Ref } from 'vue';
import { type ECOption, useEcharts } from '@/hook';
import { type ECOption, useEcharts } from '@/hooks';
const pieOptions = ref<ECOption>({
title: {

View File

@ -9,7 +9,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useClipBoard } from '@/hook';
import { useClipBoard } from '@/hooks';
const { copy } = useClipBoard();
const text = ref('Hello Clipboard');

View File

@ -1,5 +1,5 @@
<template>
<n-card title="地图示例">
<n-card title="地图示例(keepalive缓存)">
<n-tabs type="line" animated>
<n-tab-pane v-for="item in maps" :key="item.id" :name="item.id" :tab="item.label" class="h-600px">
<component :is="item.component" />
@ -7,7 +7,11 @@
</n-tabs>
</n-card>
</template>
<script lang="ts">
export default {
name: 'PluginMap', //name
};
</script>
<script setup lang="ts">
import AMap from './components/AMap.vue';
import BMap from './components/BMap.vue';

View File

@ -6,7 +6,7 @@
</template>
<script setup lang="ts">
import { useAppRouter } from '@/hook';
import { useAppRouter } from '@/hooks';
const { routerPush } = useAppRouter();
</script>