diff --git a/package.json b/package.json index 79140a3..32f0b44 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "@element-plus/icons-vue": "^2.3.2", "echarts": "^6.0.0", "element-plus": "^2.13.1", + "pinia": "^3.0.4", + "pinia-plugin-persistedstate": "^4.7.1", "vue": "^3.5.24", "vue-router": "^4.6.4" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8b349ae..ba6a8c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,12 @@ importers: element-plus: specifier: ^2.13.1 version: 2.13.1(vue@3.5.26(typescript@5.9.3)) + pinia: + specifier: ^3.0.4 + version: 3.0.4(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3)) + pinia-plugin-persistedstate: + specifier: ^4.7.1 + version: 4.7.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3))) vue: specifier: ^3.5.24 version: 3.5.26(typescript@5.9.3) @@ -587,14 +593,23 @@ packages: '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + '@vue/devtools-api@7.7.9': + resolution: {integrity: sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==} + '@vue/devtools-core@8.0.5': resolution: {integrity: sha512-dpCw8nl0GDBuiL9SaY0mtDxoGIEmU38w+TQiYEPOLhW03VDC0lfNMYXS/qhl4I0YlysGp04NLY4UNn6xgD0VIQ==} peerDependencies: vue: ^3.0.0 + '@vue/devtools-kit@7.7.9': + resolution: {integrity: sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==} + '@vue/devtools-kit@8.0.5': resolution: {integrity: sha512-q2VV6x1U3KJMTQPUlRMyWEKVbcHuxhqJdSr6Jtjz5uAThAIrfJ6WVZdGZm5cuO63ZnSUz0RCsVwiUUb0mDV0Yg==} + '@vue/devtools-shared@7.7.9': + resolution: {integrity: sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==} + '@vue/devtools-shared@8.0.5': resolution: {integrity: sha512-bRLn6/spxpmgLk+iwOrR29KrYnJjG9DGpHGkDFG82UM21ZpJ39ztUT9OXX3g+usW7/b2z+h46I9ZiYyB07XMXg==} @@ -701,6 +716,9 @@ packages: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + echarts@6.0.0: resolution: {integrity: sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==} @@ -850,6 +868,9 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + perfect-debounce@2.0.0: resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} @@ -860,6 +881,29 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pinia-plugin-persistedstate@4.7.1: + resolution: {integrity: sha512-WHOqh2esDlR3eAaknPbqXrkkj0D24h8shrDPqysgCFR6ghqP/fpFfJmMPJp0gETHsvrh9YNNg6dQfo2OEtDnIQ==} + peerDependencies: + '@nuxt/kit': '>=3.0.0' + '@pinia/nuxt': '>=0.10.0' + pinia: '>=3.0.0' + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@pinia/nuxt': + optional: true + pinia: + optional: true + + pinia@3.0.4: + resolution: {integrity: sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==} + peerDependencies: + typescript: '>=4.5.0' + vue: ^3.5.11 + peerDependenciesMeta: + typescript: + optional: true + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -1520,6 +1564,10 @@ snapshots: '@vue/devtools-api@6.6.4': {} + '@vue/devtools-api@7.7.9': + dependencies: + '@vue/devtools-kit': 7.7.9 + '@vue/devtools-core@8.0.5(vite@7.3.1(@types/node@24.10.8))(vue@3.5.26(typescript@5.9.3))': dependencies: '@vue/devtools-kit': 8.0.5 @@ -1532,6 +1580,16 @@ snapshots: transitivePeerDependencies: - vite + '@vue/devtools-kit@7.7.9': + dependencies: + '@vue/devtools-shared': 7.7.9 + birpc: 2.9.0 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.6 + '@vue/devtools-kit@8.0.5': dependencies: '@vue/devtools-shared': 8.0.5 @@ -1542,6 +1600,10 @@ snapshots: speakingurl: 14.0.1 superjson: 2.2.6 + '@vue/devtools-shared@7.7.9': + dependencies: + rfdc: 1.4.1 + '@vue/devtools-shared@8.0.5': dependencies: rfdc: 1.4.1 @@ -1651,6 +1713,8 @@ snapshots: define-lazy-prop@3.0.0: {} + defu@6.1.4: {} + echarts@6.0.0: dependencies: tslib: 2.3.0 @@ -1795,12 +1859,27 @@ snapshots: pathe@2.0.3: {} + perfect-debounce@1.0.0: {} + perfect-debounce@2.0.0: {} picocolors@1.1.1: {} picomatch@4.0.3: {} + pinia-plugin-persistedstate@4.7.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3))): + dependencies: + defu: 6.1.4 + optionalDependencies: + pinia: 3.0.4(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3)) + + pinia@3.0.4(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3)): + dependencies: + '@vue/devtools-api': 7.7.9 + vue: 3.5.26(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + postcss@8.5.6: dependencies: nanoid: 3.3.11 diff --git a/src/main.ts b/src/main.ts index a060eb1..459a0e1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,5 @@ import { createApp } from "vue"; import App from "./App.vue"; -import router from "./router"; import "@/assets/styles/index.css"; import ElementPlus from "element-plus"; import "element-plus/dist/index.css"; @@ -9,6 +8,8 @@ import * as ElementPlusIconsVue from "@element-plus/icons-vue"; import "@/assets/font/iconfont.css"; import * as echarts from "echarts"; import Components from "@/components"; +import pinia from "@/store"; +import router from "./router"; const app = createApp(App); // 全局挂载echarts @@ -17,6 +18,8 @@ app.config.globalProperties.$echarts = echarts; for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component); } + +app.use(pinia); app.use(router); app.use(Components); app.use(ElementPlus, { locale: zhCn }).mount("#app"); diff --git a/src/router/index.ts b/src/router/index.ts index 261c2a1..80c442f 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -5,6 +5,7 @@ import { } from "vue-router"; import Layout from "@/Layout/index.vue"; import Login from "@/views/login/index.vue"; +import { useUserStore } from "@/store"; const routes = [ { @@ -38,12 +39,21 @@ const routes = [ }, ], }, - { path: "/login", component: Login }, + { path: "/login", name: "Login", component: Login }, ]; const router = createRouter({ history: createWebHashHistory(), routes, }); +router.beforeEach(async (to, from) => { + const userStore = useUserStore(); + const isToken = userStore.userInfo?.token; + console.log(userStore); + if (!isToken && to.name !== "Login") { + // 将用户重定向到登录页面 + return { name: "Login" }; + } +}); export default router; diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..5720984 --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,9 @@ +import { createPinia } from "pinia"; +import persist from "pinia-plugin-persistedstate"; +const pinia = createPinia(); +// 使用持久化存储插件 +pinia.use(persist); + +export default pinia; + +export * from "./modules/user"; diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts new file mode 100644 index 0000000..686ea4c --- /dev/null +++ b/src/store/modules/user.ts @@ -0,0 +1,25 @@ +import { defineStore } from "pinia"; +import { ref } from "vue"; +interface UserInfoType { + token: string; +} +export const useUserStore = defineStore( + "user", + () => { + const userInfo = ref(); + const setUserInfo = (val: UserInfoType) => { + userInfo.value = val; + }; + const delUserInfo = () => { + userInfo.value = undefined; + }; + return { + userInfo, + setUserInfo, + delUserInfo, + }; + }, + { + persist: true, + }, +); diff --git a/src/views/login/index.vue b/src/views/login/index.vue index eae6f82..3dca02e 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -2,6 +2,9 @@ import { ref } from 'vue'; import { User, Lock } from '@element-plus/icons-vue' import { ElMessage, type FormInstance, type FormRules } from 'element-plus'; +import { useUserStore } from "@/store"; +import router from '@/router'; +const userStore = useUserStore() interface RuleForm { username: string password: string @@ -24,6 +27,7 @@ const rules = ref>({ }] }) const loginBtn = async (formEl: FormInstance | undefined) => { + if (!formEl) return await formEl.validate((valid) => { if (valid) { @@ -31,6 +35,12 @@ const loginBtn = async (formEl: FormInstance | undefined) => { message: '登录成功', type: 'success', }) + userStore.setUserInfo({ + token: 'aaaaaa' + }) + console.log(userStore.userInfo); + router.push('/') + } else { ElMessage({ message: '请输入账号密码',