第十三章:创建和登录用户相关的 useUserStore

创建 src/api/interface/account.interface.ts

创建 src/api 文件夹的目的:项目内所有的API请求,都会放在 src/api 中;
创建 src/api/interface 文件夹的目的:项目内所有的API请求的参数和返回值的接口约束,都会放在 src/api/interface 中;
创建 src/api/interface/account.interface.ts 文件夹的目的:当前登录账号相关的API请求的参数和返回值的接口约束,都会放在 src/api/interface/account.interface.ts 中;

// src/api/interface/account.interface.ts

/**
 * 登录参数
 */
export interface LoginParamsModel {
    username: string
    password: string
};

/**
 * 登录返回结果
 */
export interface LoginResModel {
    token: string
};

/**
 * 当前登录账号的详细信息
 */
export interface UserInfoModel {
    username: string
    nickname: string
    avatar: string
    email: string
    phone: string
    remark: string
    id: number
    createdAt: string
    updatedAt: string
};

创建 src/api/enum/common.enum.ts

创建目的: 项目内所有的API请求能用到的枚举约束

// src/api/enum/common.enum.ts

/**
 * API 请求返回 code 码枚举类型
 */
export enum ResCodeEnum {
    // 操作成功
    SUCCESS = 0,
    // 操作失败
    FAIL = -1,
    // 未登录
    NOT_LOGIN = -2,
    // token 过期
    TOKEN_EXPIRATION = -3,
}

创建 src/api/interface/common.interface.ts

创建目的: 项目内所有的API请求能用到的公共接口约束

// src/api/interface/common.interface.ts


import type { ResCodeEnum } from '../enum/common.enum'

/**
 * 响应数据模型
 */
export interface ResCodeMsg<D> {
    data: D
    code: ResCodeEnum
    message: string
}

创建 src/api/account.ts

创建目的:当前登录账号相关的API请求,都会放在 src/api/account.ts 中

// src/api/account.ts


import type { LoginParamsModel, LoginResModel, UserInfoModel } from './interface/account.interface'
import type { ResCodeMsg } from './interface/common.interface'
import { ResCodeEnum } from './enum/common.enum'

/**
 * 登录
 */
export function accountLogin(data: LoginParamsModel): Promise<ResCodeMsg<LoginResModel>> {
    console.log('loginParams', data)

    // 目前还没有定义 axios 请求, 先暂时模拟一下请求
    return new Promise((resolve) => {
        const timer = setTimeout(() => {
            clearTimeout(timer)

            resolve({
                code: ResCodeEnum.SUCCESS,
                message: '登录成功',
                data: {
                    token: 'mock_token',
                },
            })
        }, 1000)
    })
}

/** 获取账户资料 */
export async function accountProfile(): Promise<ResCodeMsg<UserInfoModel>> {
   // 目前还没有定义 axios 请求, 先暂时模拟一下请求
    return new Promise((resolve) => {
        const timer = setTimeout(() => {
            clearTimeout(timer)

            resolve({
                code: ResCodeEnum.SUCCESS,
                message: '登录成功',
                data: {
                     username: '萧炎',
                     nickname: '侥幸哥',
                     avatar: '',
                     email: '123456@qq.com',
                     phone: '12345678901',
                     remark: '备注信息',
                     id: 1,
                     createdAt: '2025-08-04 09:52:43',
                     updatedAt: '',
                },
            })
        }, 1000)
    })
}

/** 退出登录 */
export function accountLogout(): Promise<ResCodeMsg<null>> {
    // 目前还没有定义 axios 请求, 先暂时模拟一下请求
    return new Promise((resolve) => {
        const timer = setTimeout(() => {
            clearTimeout(timer)

            resolve({
                code: ResCodeEnum.SUCCESS,
                message: '退出登录成功',
                data: null,
            })
        }, 1000)
    })
}


创建 src/store/modules/user.ts 并实现 useUserStore

import type { LoginParamsModel, UserInfoModel } from '@/api/interface/account.interface'
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { accountLogin, accountLogout, accountProfile } from '@/api/account'
import { ResCodeEnum } from '@/api/enum/common.enum'

export const useUserStore = defineStore(
    'user',
    () => {
         const token = ref<string>()
         const userInfo = ref<Partial<UserInfoModel>>({})

         /** 清空登录态 */
         const clearLoginStatus = () => {
             token.value = '';
             userInfo.value = {};
             localStorage.clear();
         };
 
         /** 登录成功保存token */
         const setToken = (_token: string) => {
             token.value = _token
         }

         /** 登录成功之后, 获取用户信息 */
         const afterLogin = async () => {
             try {
                 const response= await accountProfile()
                 if (response.code !== ResCodeEnum.SUCCESS) {
                     message.warning(response.message)
                     return;
                 }
                 userInfo.value = response.data
             }
             catch (error) {
                 return Promise.reject(error)
             }
         }

         /** 登录 */
         const login = async (params: LoginParamsModel) => {
             try {
                 const response= await accountLogin(params)
                 if (response.code !== ResCodeEnum.SUCCESS) {
                     message.warning(response.message)
                     return 
                 }
                 setToken(response.data.token)
                 await afterLogin()
             }
             catch (error) {
                 return Promise.reject(error)
             }
         }

         /** 登出 */
         const logout = async () => {
             await accountLogout()
             clearLoginStatus()
         }

         return {  token, userInfo, login, afterLogin, logout, clearLoginStatus  };
    },
    {
         persist: {
             // 只将 token 和 userInfo 持久化到本地缓存中
             pick: ['token',  'userInfo'], 
         },
    }
);
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容