• 【Vue】Pinia管理用户数据


    Pinia管理用户数据

    基本思想:Pinia负责用户数据相关的state和action,组件中只负责触发action函数并传递参数

    步骤1:创建userStore

    1-创建store/userStore.js

    import { loginAPI } from '@/apis/user'
    export const useUserStore = defineStore('user', () => {
        // 1. 定义管理用户数据的state
        const userInfo = ref({})
        // 2. 定义获取接口数据的action函数
        const getUserInfo = async (user) => {
            const res = await loginAPI(user)
            userInfo.value = res.result
        }
        // 3. 以对象的格式把state和action return
        return {
            userInfo,
            getUserInfo,
        }
    })
    

    2-重构login.vue

    import {useUserStore} from "@/stores/userStore";
    
    
    const userStore = useUserStore();
    ...
    //form实例统一校验
    const formRef = ref(null);
    const router = useRouter();
    const doLogin = () => {
      formRef.value.validate(async (valid) => {
        // valid: 所有表单都通过校验  才为true
        //console.log(valid)
        if (valid) {
          //console.log(form.value)
          const {account, password} = form.value
          //const res = await loginAPI({account, password});
          const res = await userStore.getUserInfo({account, password});
          //console.log(res)
          ElMessage({type: 'success', message: '登录成功'})
          router.replace({path: '/'})
        }
      })
    }
    

    步骤2:重构导航栏用户登录状态模板

    重构LayoutNav.vue

    <script setup>
    import {useUserStore} from "@/stores/userStore";
    const userStore = useUserStore();
    script>
    
    <template>
      <nav class="app-topnav">
        <div class="container">
          <ul>
            <template v-if="userStore.userInfo.token">
              <li><a href="javascript:;"><i class="iconfont icon-user">i>{{ userStore.userInfo.account }}a>li>
    

    步骤3:用户数据持久化

    1-安装pinia数据持久化插件

    npm i pinia-plugin-persistedstate
    

    2-重构main.js

    import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
    
    const app = createApp(App)
    const pinia = createPinia();
    pinia.use(piniaPluginPersistedstate)
    app.use(pinia)
    

    3-重构userStore.js

    export const useUserStore = defineStore('user', () => {
        // 1. 定义管理用户数据的state
        const userInfo = ref({})
        // 2. 定义获取接口数据的action函数
        const getUserInfo = async (user) => {
            const res = await loginAPI(user)
            userInfo.value = res.result
        }
        // 3. 以对象的格式把state和action return
        return {
            userInfo,
            getUserInfo,
        }
    },{
        persist:true
    })
    

    4-重启服务器,测试数据持久性

    在这里插入图片描述

    退出登录实现

    基础思想:

    1. 清除用户信息
    2. 跳转到登录页

    1- 新增清除用户信息action

     // 退出时清除用户信息
      const clearUserInfo = () => {
        userInfo.value = {}
      }
    

    2- 组件中执行业务逻辑

    <script setup>
    import { useUserStore } from '@/stores/userStore'
    import { useRouter } from 'vue-router'
    const userStore = useUserStore()
    const router = useRouter()
    const confirm = () => {
      console.log('用户要退出登录了')
      // 退出登录业务逻辑实现
      // 1.清除用户信息 触发action
      userStore.clearUserInfo()
      // 2.跳转到登录页
      router.push('/login')
    }
    script>
    
    <el-popconfirm @confirm="confirm" title="确认退出吗?" confirm-button-text="确认" cancel-button-text="取消">
                  <template #reference>
                    <a href="javascript:;">退出登录a>
                  template>
                el-popconfirm>
    

    token相关设置

    ##请求拦截器携带token

    基础思想:很多接口如果想要获取数据必须要带着有效的Token信息才可以,拦截器中做一次,用到axios实例的其他都可以拿到

    // axios请求拦截器
    http.interceptors.request.use(config => {
        const userStore = useUserStore();
        const token = userStore.userInfo.token;
        if(token){
            config.headers.Authorization = `Bearer ${token}`
        }
        return config
    }, e => Promise.reject(e))
    

    请求测试效果
    在这里插入图片描述

    响应拦截器处理token失效

    // axios响应式拦截器
    http.interceptors.response.use(res => res.data, e => {    
        //统一错误提示
        ElMessage({
            type: 'error',
            message: e.response.data.message
        })
        //401token失效处理
        const userStore = useUserStore();
        if(e.response.status === 401){
            userStore.clearUserInfo()
            router.push('/login')
        }
    
        return Promise.reject(e)
    })
    
  • 相关阅读:
    关于SqlSugar的多对多的级联插入的问题(无法获取集合属性的id,导致无法维护中间表)
    CMU15445 (Fall 2019) 之 Project#3 - Query Execution 详解
    [附源码]计算机毕业设计JAVAjsp智慧农产品朔源系统
    一道面试题:介绍一下 Fragment 间的通信方式?
    Dubbo 架构介绍
    张鑫溢:9.8现货黄金震荡走弱,一度刷新三个交易日低点.黄金行情趋势分析及黄金原油独家操作建议指导.
    如何创建自己的小程序?
    PostgreSQL11 | 初识PostgreSQL
    java 电动车销售管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
    Flink学习(二)-基础概念
  • 原文地址:https://blog.csdn.net/Jerryqjr/article/details/139701872