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: '地图', title: '地图',
requiresAuth: true, requiresAuth: true,
icon: 'carbon:map', icon: 'carbon:map',
keepAlive: true,
}, },
}, },
{ {
@ -271,6 +272,16 @@ const userRoutes = [
icon: 'logos:vitejs', 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> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useAppRouter } from '@/hook'; import { useAppRouter } from '@/hooks';
type TipType = '403' | '404' | '500'; type TipType = '403' | '404' | '500';
defineProps<{ defineProps<{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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