vue登录最佳实现
使用 Vuex 管理登录状态
Vuex 是 Vue 的官方状态管理库,适合集中管理登录状态。在 store 中定义 user 模块,存储用户信息和登录状态。通过 mutations 更新状态,actions 处理异步逻辑(如 API 调用)。
// store/modules/user.js
const state = {
token: localStorage.getItem('token') || '',
userInfo: null
};
const mutations = {
SET_TOKEN(state, token) {
state.token = token;
localStorage.setItem('token', token);
},
SET_USER_INFO(state, userInfo) {
state.userInfo = userInfo;
}
};
const actions = {
async login({ commit }, credentials) {
const response = await api.login(credentials);
commit('SET_TOKEN', response.data.token);
commit('SET_USER_INFO', response.data.user);
}
};
路由守卫控制访问权限
通过 Vue Router 的全局前置守卫 beforeEach,检查用户是否登录。未登录用户访问受限路由时,重定向到登录页。
// router/index.js
router.beforeEach((to, from, next) => {
const isAuthenticated = store.state.user.token;
if (to.meta.requiresAuth && !isAuthenticated) {
next('/login');
} else {
next();
}
});
封装登录 API 请求
使用 axios 封装登录接口,统一处理请求和响应。添加拦截器处理 token 的自动注入和错误响应。
// api/auth.js
import axios from 'axios';
const api = axios.create({
baseURL: 'https://api.example.com/auth'
});
api.interceptors.request.use(config => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
export const login = credentials => api.post('/login', credentials);
表单验证与用户体验
使用 Vuelidate 或原生 HTML5 验证确保输入合法性。登录失败时显示友好错误提示,避免直接暴露后端错误细节。
<template>
<form @submit.prevent="handleLogin">
<input v-model="email" type="email" required placeholder="Email">
<input v-model="password" type="password" required placeholder="Password">
<button type="submit" :disabled="isLoading">
{{ isLoading ? 'Logging in...' : 'Login' }}
</button>
<p v-if="error" class="error">{{ error }}</p>
</form>
</template>
持久化登录状态
通过 localStorage 或 cookie 存储 token,页面刷新后仍保持登录状态。注意敏感信息需加密或使用 HttpOnly cookie 增强安全性。
// 登录成功后存储 token
localStorage.setItem('token', token);
// 退出时清除
localStorage.removeItem('token');
处理 Token 过期
在 axios 响应拦截器中检查 token 过期,触发自动刷新或强制退出。
api.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
store.dispatch('logout');
router.push('/login');
}
return Promise.reject(error);
}
);






