【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)
})
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue 3 Pinia 是一个基于 Vue 3 的状态管理库,它提供了一种简单且高效的方式来存储和管理应用程序的数据。Pinia 的核心概念是使用 Store 来存储数据,并通过使用类似于 Vuex 的方式来访问和修改数据。 要使用 Pinia 存储数据,首先需要创建一个 Store。可以通过定义一个类来创建 Store,并在类中定义数据和方法。以下是一个简单的示例: ```javascript import { createPinia } from 'pinia'; const pinia = createPinia(); class MyStore { // 定义数据 count = 0; // 定义方法 increment() { this.count++; } decrement() { this.count--; } } // 注册 Store pinia.use(MyStore); export default pinia; ``` 在上面的示例中,我们创建了一个名为 MyStore 的 Store,并定义了一个名为 count 的数据和两个方法 increment 和 decrement。接下来,我们需要在应用程序的入口文件中注册 Store。 ```javascript import { createApp } from 'vue'; import App from './App.vue'; import pinia from './pinia'; const app = createApp(App); // 注册 Pinia app.use(pinia); app.mount('#app'); ``` 现在,我们可以在组件中使用 Store 来存储和访问数据。以下是一个使用 Store 的组件示例: ```vue <template> <div> <p>Count: {{ $store.count }}</p> <button @click="$store.increment()">Increment</button> <button @click="$store.decrement()">Decrement</button> </div> </template> <script> export default { name: 'MyComponent', }; </script> ``` 在上面的示例中,我们通过 `$store` 访问 Store 中的数据和方法。通过 `$store.count` 可以获取 count 的值,通过 `$store.increment()` 和 `$store.decrement()` 可以调用对应的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jerry_ww

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值