本文檔詳細說(shuō)明了 await userStore.login(formData.value)
這行代碼的工作原理,以及如何根據您的需求進(jìn)行修改。
// src/pages/login/components/Login.vue 第139行
await userStore.login(formData.value);
這行代碼的作用:
graph TD
A[用戶(hù)點(diǎn)擊登錄](méi) --> B[表單驗證]
B --> C[調用 userStore.login]
C --> D[發(fā)送登錄請求]
D --> E{登錄成功?}
E -->|是| F[保存token]
E -->|否| G[顯示錯誤信息]
F --> H[跳轉到首頁(yè)]
G --> I[停留在登錄頁(yè)]
const onSubmit = async (ctx: SubmitContext) => {
if (ctx.validateResult === true) {
try {
// ?? 核心登錄調用
await userStore.login(formData.value);
MessagePlugin.success('登錄成功');
const redirect = route.query.redirect as string;
const redirectUrl = redirect ? decodeURIComponent(redirect) : '/dashboard';
router.push(redirectUrl);
} catch (e) {
console.log(e);
MessagePlugin.error(e.message);
}
}
};
// src/store/modules/user.ts
async login(userInfo: Record<string, unknown>) {
const mockLogin = async (userInfo: Record<string, unknown>) => {
// ?? 當前是模擬登錄,沒(méi)有真實(shí)API調用
console.log(`用戶(hù)信息:`, userInfo);
// 注釋掉的驗證邏輯
// const { account, password } = userInfo;
// if (account !== 'td') {
// return { code: 401, message: '賬號不存在' };
// }
// if (['main_', 'dev_'].indexOf(password) === -1) {
// return { code: 401, message: '密碼錯誤' };
// }
return {
code: 200,
message: '登錄成功',
data: 'main_token',
};
};
const res = await mockLogin(userInfo);
if (res.code === 200) {
this.token = res.data;
} else {
throw res;
}
}
// src/api/auth.ts
import request from '@/utils/request';
export interface LoginParams {
account: string;
password: string;
phone?: string;
verifyCode?: string;
}
export interface LoginResponse {
code: number;
message: string;
data: {
token: string;
userInfo: {
id: string;
name: string;
email: string;
roles: string[];
};
};
}
// 賬號密碼登錄
export const loginWithPassword = (params: LoginParams): Promise<LoginResponse> => {
return request.post('/api/auth/login', {
username: params.account,
password: params.password,
});
};
// 手機號驗證碼登錄
export const loginWithPhone = (params: LoginParams): Promise<LoginResponse> => {
return request.post('/api/auth/login-phone', {
phone: params.phone,
code: params.verifyCode,
});
};
// 發(fā)送驗證碼
export const sendVerificationCode = (phone: string): Promise<any> => {
return request.post('/api/auth/send-code', { phone });
};
// src/store/modules/user.ts
import { loginWithPassword, loginWithPhone } from '@/api/auth';
export const useUserStore = defineStore('user', {
// ... 其他代碼
actions: {
async login(userInfo: Record<string, unknown>) {
try {
let res;
// 根據登錄類(lèi)型選擇不同的API
if (userInfo.phone && userInfo.verifyCode) {
// 手機號登錄
res = await loginWithPhone(userInfo as LoginParams);
} else {
// 賬號密碼登錄
res = await loginWithPassword(userInfo as LoginParams);
}
if (res.code === 200) {
// 保存token
this.token = res.data.token;
// 保存用戶(hù)信息
this.userInfo = {
name: res.data.userInfo.name,
roles: res.data.userInfo.roles,
};
return res;
} else {
throw new Error(res.message);
}
} catch (error) {
console.error('登錄失敗:', error);
throw error;
}
},
// ... 其他方法
},
});
// src/pages/login/components/Login.vue
const onSubmit = async (ctx: SubmitContext) => {
if (ctx.validateResult === true) {
try {
// 添加加載狀態(tài)
const loading = MessagePlugin.loading('登錄中...');
// ?? 調用登錄
await userStore.login(formData.value);
loading.close();
MessagePlugin.success('登錄成功');
// 獲取用戶(hù)信息
await userStore.getUserInfo();
// 跳轉邏輯
const redirect = route.query.redirect as string;
const redirectUrl = redirect ? decodeURIComponent(redirect) : '/dashboard';
await router.push(redirectUrl);
} catch (error) {
console.error('登錄失敗:', error);
// 錯誤處理
if (error.code === 401) {
MessagePlugin.error('用戶(hù)名或密碼錯誤');
} else if (error.code === 403) {
MessagePlugin.error('賬號已被禁用');
} else {
MessagePlugin.error(error.message || '登錄失敗,請重試');
}
// 清空密碼
formData.value.password = '';
}
}
};
// 在 userStore.login 中添加不同登錄方式的處理
async login(userInfo: Record<string, unknown>) {
const { account, password, phone, verifyCode } = userInfo;
try {
let loginData;
// 判斷登錄方式
if (phone && verifyCode) {
// 手機號驗證碼登錄
loginData = await this.phoneLogin({ phone, verifyCode });
} else if (account && password) {
// 賬號密碼登錄
loginData = await this.passwordLogin({ account, password });
} else {
throw new Error('請填寫(xiě)完整的登錄信息');
}
// 統一處理登錄結果
if (loginData.code === 200) {
this.token = loginData.data.token;
this.userInfo = loginData.data.userInfo;
} else {
throw new Error(loginData.message);
}
} catch (error) {
throw error;
}
},
// 賬號密碼登錄
async passwordLogin({ account, password }) {
return await loginWithPassword({ account, password });
},
// 手機號登錄
async phoneLogin({ phone, verifyCode }) {
return await loginWithPhone({ phone, verifyCode });
},
// src/api/auth.ts
export const loginWithPassword = (params: LoginParams) => {
return request.post('/your-api/login', params); // 修改為您的API地址
};
export const loginWithPassword = (params: LoginParams) => {
return request.post('/api/auth/login', {
// 根據后端要求調整參數名
username: params.account, // account -> username
password: params.password,
loginType: 'password', // 添加登錄類(lèi)型
});
};
// Login.vue
const onSubmit = async (ctx: SubmitContext) => {
if (ctx.validateResult === true) {
try {
await userStore.login({
...formData.value,
rememberMe: formData.value.checked, // 添加記住密碼標識
});
// 如果選擇記住密碼,保存到本地存儲
if (formData.value.checked) {
localStorage.setItem('rememberedAccount', formData.value.account);
}
// ... 其他邏輯
} catch (error) {
// ... 錯誤處理
}
}
};
// userStore
const MAX_LOGIN_ATTEMPTS = 5;
let loginAttempts = 0;
async login(userInfo: Record<string, unknown>) {
if (loginAttempts >= MAX_LOGIN_ATTEMPTS) {
throw new Error('登錄失敗次數過(guò)多,請稍后再試');
}
try {
const res = await loginWithPassword(userInfo);
if (res.code === 200) {
loginAttempts = 0; // 重置失敗次數
this.token = res.data.token;
} else {
loginAttempts++;
throw new Error(res.message);
}
} catch (error) {
loginAttempts++;
throw error;
}
}
// src/pages/login/components/Login.vue
const onSubmit = async (ctx: SubmitContext) => {
if (ctx.validateResult === true) {
const loading = MessagePlugin.loading('登錄中...');
try {
// 調用登錄
const result = await userStore.login(formData.value);
loading.close();
MessagePlugin.success('登錄成功');
// 獲取用戶(hù)詳細信息
await userStore.getUserInfo();
// 跳轉到目標頁(yè)面
const redirect = route.query.redirect as string;
const redirectUrl = redirect ? decodeURIComponent(redirect) : '/dashboard';
await router.push(redirectUrl);
} catch (error) {
loading.close();
console.error('登錄失敗:', error);
// 根據錯誤類(lèi)型顯示不同消息
const errorMessages = {
401: '用戶(hù)名或密碼錯誤',
403: '賬號已被禁用',
429: '登錄失敗次數過(guò)多,請稍后再試',
500: '服務(wù)器錯誤,請稍后再試',
};
const message = errorMessages[error.code] || error.message || '登錄失敗';
MessagePlugin.error(message);
// 清空敏感信息
if (error.code === 401) {
formData.value.password = '';
}
}
}
};
await userStore.login(formData.value)
這行代碼是整個(gè)登錄流程的核心,您可以根據需要:
根據您的具體需求選擇合適的修改方案即可。
最后更新: 2025/10/3