feat: route和store

This commit is contained in:
caoqianming 2025-10-29 22:45:18 +08:00
parent 28d57c8c39
commit e5d8fc7ac3
6 changed files with 81 additions and 41 deletions

View File

@ -7,7 +7,7 @@
<title>XT_WEB_TD</title>
</head>
<body>
<div id="app"></div>
<div id="app" style="height: 100vh;"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

20
package-lock.json generated
View File

@ -15,7 +15,6 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.1",
"prettier": "^3.6.2",
"vite": "^7.1.7"
}
},
@ -1166,6 +1165,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@ -1201,22 +1201,6 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/prettier": {
"version": "3.6.2",
"resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.6.2.tgz",
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/rollup": {
"version": "4.52.5",
"resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.52.5.tgz",
@ -1351,6 +1335,7 @@
"integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",
@ -1425,6 +1410,7 @@
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.22.tgz",
"integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.22",
"@vue/compiler-sfc": "3.5.22",

View File

@ -1,35 +1,48 @@
<template>
<div>
<t-layout style="height: 100vh;width: 100vw;">
<t-aside>
<t-menu theme="light" default-value="item1" style="margin-right: 40px" @change="handleMenuChange" v-model="activeMenu">
<template #logo>
<img height="28" src="https://tdesign.gtimg.com/site/baseLogo-light.png" alt="logo" />
</template>
<t-menu-item v-for="route in menuRoutes" :key="route.name" :value="route.name"
:disabled="route.meta?.disabled">
{{ route.name }}
</t-menu-item>
</t-menu>
</t-aside>
<t-layout>
<t-layout style="height:100%">
<t-header>
<t-head-menu theme="light">
<template #logo>
<img height="28" src="https://tdesign.gtimg.com/site/baseLogo-light.png" alt="logo" />
<!-- <span style="font-size: 18px; font-weight: 600;">XT_WEB_TD</span> -->
</template>
<template #operations>
<t-button theme="warning" @click="handleQuit">退出</t-button>
<t-button variant="outline" :icon="user">{{ userInfo.name }}
</t-button>
<t-button variant="text" shape="square" @click="handleQuit" style="margin-left: 2px;">
<template #icon><t-icon name="logout" style="color: #ff0000;"/></template>
</t-button>
</template>
</t-head-menu>
</t-header>
<t-content>
<t-layout>
<t-aside style="border-top: 1px solid #e5e5e5;" width="160px">
<t-menu theme="light" default-value="item1" @change="handleMenuChange"
v-model="activeMenu" width="160px">
<t-menu-item v-for="route in menuRoutes" :key="route.name" :value="route.name"
:disabled="route.meta?.disabled">
{{ route.name }}
<template #icon v-if="route.meta?.icon">
<t-icon :name="route.meta.icon" />
</template>
</t-menu-item>
<!-- <template #operations>
<t-button variant="text" shape="square" @click="changeCollapsed">
<template #icon><t-icon :name="iconName" /></template>
</t-button>
</template> -->
</t-menu>
</t-aside>
<t-content style="border-top: 1px solid #e5e5e5;">
<router-view />
</t-content>
</t-layout>
</t-layout>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { authToken, userInfo } from '@/store/index.js'
const router = useRouter();
const route = useRoute();
@ -54,6 +67,8 @@ watch(() => route.name, (newName) => {
}, { immediate: true })
const handleQuit = () => {
window.location.replace('/login')
authToken.access = null
authToken.refresh = null
router.replace('/login')
}
</script>

View File

@ -13,7 +13,7 @@
</t-input>
</t-form-item>
<t-form-item>
<t-input type="password" v-model="password" size="large">
<t-input type="password" v-model="formData.password" size="large">
<template #prefix-icon>
<t-icon name="lock-on" />
</template>
@ -30,6 +30,7 @@
<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { authToken } from '@/store/index.js'
const router = useRouter();
const formData = ref({
username: "",
@ -39,8 +40,9 @@ const submitLoading = ref(false);
const handleLogin = () => {
submitLoading.value = true;
setTimeout(() => {
authToken.access = "123456";
submitLoading.value = false;
router.push({ path: "/home" });
router.replace({ path: "/home" });
}, 300);
}
</script>

View File

@ -1,4 +1,5 @@
import { createRouter, createWebHistory} from 'vue-router';
import { authToken } from '@/store/index.js'
const routes = [
{ path: "/", redirect: "/login" },
{
@ -14,16 +15,19 @@ const routes = [
{
path: "",
name: "工作台",
meta: { icon: "file"},
children: [
{
path: "home",
name: "主页",
component: () => import("@/pages/home/index.vue"),
meta: { icon: "app"},
},
{
path: "user",
name: "用户管理",
component: () => import("@/pages/system/user.vue"),
meta: { icon: "app"},
},
],
},
@ -37,4 +41,20 @@ const router = createRouter({
routes,
});
router.beforeEach((to, from, next) => {
if (to.path === "/login") {
if (authToken.access) {
next("/home");
} else {
next();
}
} else {
if (authToken.access) {
next();
} else {
next("/login");
}
}
})
export default router;

17
src/store/index.js Normal file
View File

@ -0,0 +1,17 @@
import { reactive, watch } from "vue";
export const userInfo = reactive(JSON.parse(localStorage.getItem("userInfo")) || {
name: "张三",
username: "zhangsan"
});
watch(userInfo, (newVal) => {
localStorage.setItem("userInfo", JSON.stringify(newVal));
}, { deep: true, immediate: true})
export const authToken = reactive(JSON.parse(localStorage.getItem("authToken")) ||{
access: null,
refresh: null
})
watch(authToken, (newVal) => {
localStorage.setItem("authToken", JSON.stringify(newVal));
}, { deep: true, immediate: true})