mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-07 08:46:40 +08:00
use vuex
This commit is contained in:
@@ -37,6 +37,8 @@
|
|||||||
"vue3-apexcharts": "^1.4.1",
|
"vue3-apexcharts": "^1.4.1",
|
||||||
"vue3-perfect-scrollbar": "^1.6.0",
|
"vue3-perfect-scrollbar": "^1.6.0",
|
||||||
"vuetify": "3.2.1",
|
"vuetify": "3.2.1",
|
||||||
|
"vuex": "^4.1.0",
|
||||||
|
"vuex-persistedstate": "^4.1.0",
|
||||||
"webfontloader": "^1.6.28"
|
"webfontloader": "^1.6.28"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import router from '@/router'
|
import router from '@/router';
|
||||||
import avatar1 from '@images/avatars/avatar-1.png'
|
import avatar1 from '@images/avatars/avatar-1.png';
|
||||||
|
import { useStore } from 'vuex';
|
||||||
|
|
||||||
|
// Vuex Store
|
||||||
|
const store = useStore();
|
||||||
|
|
||||||
// 执行注销操作
|
// 执行注销操作
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
// 清除登录状态信息,例如删除令牌
|
// 清除登录状态信息
|
||||||
localStorage.removeItem('token')
|
store.dispatch('clearToken');
|
||||||
|
|
||||||
// 重定向到登录页面或其他适当的页面
|
// 重定向到登录页面或其他适当的页面
|
||||||
router.push('/login')
|
router.push('/login')
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import App from '@/App.vue'
|
|||||||
import vuetify from '@/plugins/vuetify'
|
import vuetify from '@/plugins/vuetify'
|
||||||
import { loadFonts } from '@/plugins/webfontloader'
|
import { loadFonts } from '@/plugins/webfontloader'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
import store from '@/store'
|
||||||
import '@core/scss/template/index.scss'
|
import '@core/scss/template/index.scss'
|
||||||
import '@layouts/styles/index.scss'
|
import '@layouts/styles/index.scss'
|
||||||
import '@styles/styles.scss'
|
import '@styles/styles.scss'
|
||||||
@@ -18,6 +19,7 @@ const app = createApp(App)
|
|||||||
// Use plugins
|
// Use plugins
|
||||||
app.use(vuetify)
|
app.use(vuetify)
|
||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
|
app.use(store)
|
||||||
app.use(router)
|
app.use(router)
|
||||||
|
|
||||||
// Mount vue app
|
// Mount vue app
|
||||||
|
|||||||
+18
-15
@@ -1,8 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '@/api'
|
import api from '@/api';
|
||||||
import router from '@/router'
|
import router from '@/router';
|
||||||
import logo from '@images/logo.svg?raw'
|
import logo from '@images/logo.svg?raw';
|
||||||
|
import { useStore } from 'vuex';
|
||||||
|
|
||||||
|
// Vuex Store
|
||||||
|
const store = useStore();
|
||||||
|
|
||||||
|
// 表单
|
||||||
const form = ref({
|
const form = ref({
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
@@ -54,13 +59,11 @@ const login = () => {
|
|||||||
})
|
})
|
||||||
.then((response: any) => {
|
.then((response: any) => {
|
||||||
// 获取token
|
// 获取token
|
||||||
const token = response.access_token
|
const token = response.access_token;
|
||||||
|
|
||||||
// 将token保存在本地存储中,用于后续请求
|
// 更新token和remember状态到Vuex Store
|
||||||
localStorage.setItem('token', token)
|
store.dispatch('updateToken', token);
|
||||||
|
store.dispatch('updateRemember', form.value.remember);
|
||||||
// 保存保持登录状态
|
|
||||||
localStorage.setItem('remember', form.value.remember.toString())
|
|
||||||
|
|
||||||
// 跳转到首页
|
// 跳转到首页
|
||||||
router.push('/')
|
router.push('/')
|
||||||
@@ -86,14 +89,12 @@ const login = () => {
|
|||||||
|
|
||||||
// 自动登录
|
// 自动登录
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 获取token
|
// 从Vuex Store中获取token和remember状态
|
||||||
const token = localStorage.getItem('token')
|
const token = store.getters.getToken;
|
||||||
|
const remember = store.getters.getRemember;
|
||||||
// 获取保持登录状态
|
|
||||||
const remember = localStorage.getItem('remember')
|
|
||||||
|
|
||||||
// 如果token存在,且保持登录状态为true,则跳转到首页
|
// 如果token存在,且保持登录状态为true,则跳转到首页
|
||||||
if (token && remember === 'true') {
|
if (token && remember) {
|
||||||
router.push('/')
|
router.push('/')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -190,6 +191,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@use "@core/scss/pages/page-auth.scss";
|
@use "@core/scss/pages/page-auth.scss";
|
||||||
|
|
||||||
.fade-in {
|
.fade-in {
|
||||||
animation: fadeIn 1s ease-in;
|
animation: fadeIn 1s ease-in;
|
||||||
}
|
}
|
||||||
@@ -198,6 +200,7 @@ onMounted(() => {
|
|||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-14
@@ -1,4 +1,5 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import store from '@/store';
|
||||||
|
import { createRouter, createWebHistory } from 'vue-router';
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
@@ -103,23 +104,15 @@ const router = createRouter({
|
|||||||
|
|
||||||
// 导航守卫
|
// 导航守卫
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
const isAuthenticated = checkLoginStatus() // 检查用户是否已登录
|
// 通过 Vuex Store 检查用户是否已登录
|
||||||
|
const isAuthenticated = store.getters.getToken !== null;
|
||||||
if (to.meta.requiresAuth && !isAuthenticated) {
|
if (to.meta.requiresAuth && !isAuthenticated) {
|
||||||
// 如果路由需要登录权限且用户未登录,则跳转到登录页面
|
// 如果路由需要登录权限且用户未登录,则跳转到登录页面
|
||||||
next('/login')
|
next('/login');
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// 否则,允许继续进行路由导航
|
// 否则,允许继续进行路由导航
|
||||||
next()
|
next();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 检查用户登录状态的函数
|
|
||||||
function checkLoginStatus() {
|
|
||||||
// 在此处检查用户的登录状态,例如从本地存储中读取令牌或其他登录相关的信息
|
|
||||||
const token = localStorage.getItem('token')
|
|
||||||
|
|
||||||
return !!token // 返回一个布尔值,表示用户是否已登录
|
|
||||||
}
|
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import { ActionTree, GetterTree, MutationTree, createStore } from 'vuex';
|
||||||
|
import createPersistedState from 'vuex-persistedstate';
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
// 登录token
|
||||||
|
token: string | null;
|
||||||
|
// 是否记住登录状态
|
||||||
|
remember: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const state: State = {
|
||||||
|
token: null,
|
||||||
|
remember: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mutations: MutationTree<State> = {
|
||||||
|
setToken(state, token: string) {
|
||||||
|
state.token = token;
|
||||||
|
},
|
||||||
|
clearToken(state) {
|
||||||
|
state.token = null;
|
||||||
|
},
|
||||||
|
setRemember(state, remember: boolean) {
|
||||||
|
state.remember = remember;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const actions: ActionTree<State, any> = {
|
||||||
|
updateToken({ commit }, token: string) {
|
||||||
|
commit('setToken', token);
|
||||||
|
},
|
||||||
|
clearToken({ commit },) {
|
||||||
|
commit('clearToken');
|
||||||
|
},
|
||||||
|
updateRemember({ commit }, remember: boolean) {
|
||||||
|
commit('setRemember', remember);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const getters: GetterTree<State, any> = {
|
||||||
|
getToken: state => state.token,
|
||||||
|
getRemember: state => state.remember,
|
||||||
|
};
|
||||||
|
|
||||||
|
const store = createStore({
|
||||||
|
state,
|
||||||
|
mutations,
|
||||||
|
actions,
|
||||||
|
getters,
|
||||||
|
plugins: [
|
||||||
|
createPersistedState({
|
||||||
|
// 配置持久化存储的选项
|
||||||
|
storage: window.localStorage, // 使用 localStorage 存储状态
|
||||||
|
key: 'moviepilot', // 存储的键名
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
export default store;
|
||||||
@@ -2282,7 +2282,7 @@
|
|||||||
"@vue/compiler-dom" "3.3.2"
|
"@vue/compiler-dom" "3.3.2"
|
||||||
"@vue/shared" "3.3.2"
|
"@vue/shared" "3.3.2"
|
||||||
|
|
||||||
"@vue/devtools-api@^6.2.1", "@vue/devtools-api@^6.5.0":
|
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.2.1", "@vue/devtools-api@^6.5.0":
|
||||||
version "6.5.0"
|
version "6.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz#98b99425edee70b4c992692628fa1ea2c1e57d07"
|
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz#98b99425edee70b4c992692628fa1ea2c1e57d07"
|
||||||
integrity sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==
|
integrity sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==
|
||||||
@@ -6034,6 +6034,11 @@ shepherd.js@^11.1.0:
|
|||||||
"@floating-ui/dom" "^1.2.5"
|
"@floating-ui/dom" "^1.2.5"
|
||||||
deepmerge "^4.3.1"
|
deepmerge "^4.3.1"
|
||||||
|
|
||||||
|
shvl@^2.0.3:
|
||||||
|
version "2.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/shvl/-/shvl-2.0.3.tgz#eb4bd37644f5684bba1fc52c3010c96fb5e6afd1"
|
||||||
|
integrity sha512-V7C6S9Hlol6SzOJPnQ7qzOVEWUQImt3BNmmzh40wObhla3XOYMe4gGiYzLrJd5TFa+cI2f9LKIRJTTKZSTbWgw==
|
||||||
|
|
||||||
side-channel@^1.0.4:
|
side-channel@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
|
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
|
||||||
@@ -6977,6 +6982,21 @@ vuetify@3.2.1:
|
|||||||
resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-3.2.1.tgz#caa1d306a3ef8d52d300be4c7f6d94dc4fd897e4"
|
resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-3.2.1.tgz#caa1d306a3ef8d52d300be4c7f6d94dc4fd897e4"
|
||||||
integrity sha512-XOGfDuDGG4j/dJSu73JrkfrGB141LoiLyoZecGtUou24xMf17Rnk+pzOH+YYRVgQ7HFc4kG95DzFmAXS5ysEGA==
|
integrity sha512-XOGfDuDGG4j/dJSu73JrkfrGB141LoiLyoZecGtUou24xMf17Rnk+pzOH+YYRVgQ7HFc4kG95DzFmAXS5ysEGA==
|
||||||
|
|
||||||
|
vuex-persistedstate@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vuex-persistedstate/-/vuex-persistedstate-4.1.0.tgz#127165f85f5b4534fb3170a5d3a8be9811bd2a53"
|
||||||
|
integrity sha512-3SkEj4NqwM69ikJdFVw6gObeB0NHyspRYMYkR/EbhR0hbvAKyR5gksVhtAfY1UYuWUOCCA0QNGwv9pOwdj+XUQ==
|
||||||
|
dependencies:
|
||||||
|
deepmerge "^4.2.2"
|
||||||
|
shvl "^2.0.3"
|
||||||
|
|
||||||
|
vuex@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.1.0.tgz#aa1b3ea5c7385812b074c86faeeec2217872e36c"
|
||||||
|
integrity sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==
|
||||||
|
dependencies:
|
||||||
|
"@vue/devtools-api" "^6.0.0-beta.11"
|
||||||
|
|
||||||
webfontloader@^1.6.28:
|
webfontloader@^1.6.28:
|
||||||
version "1.6.28"
|
version "1.6.28"
|
||||||
resolved "https://registry.yarnpkg.com/webfontloader/-/webfontloader-1.6.28.tgz#db786129253cb6e8eae54c2fb05f870af6675bae"
|
resolved "https://registry.yarnpkg.com/webfontloader/-/webfontloader-1.6.28.tgz#db786129253cb6e8eae54c2fb05f870af6675bae"
|
||||||
|
|||||||
Reference in New Issue
Block a user