vue3笔记_登陆2_token持久化

537 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

如果没有持久化,登陆后,页面关闭登陆就失效了,所以需要把token存到Storage里面

pinia-plugin-persist

前面章节使用的pinia作为通信组件,pinia还支持第三方插件,这里使用插件pinia-plugin-persist 来实现持久化存储

安装

npm i pinia-plugin-persist -S

在pinia/index.js 引入

import piniaPluginPersist from "pinia-plugin-persist"

store.use(piniaPluginPersist)

persist持久化逻辑

在pinia新建一个user.js文件,定义一个token变量,创建存储和获取方法

persist配置:

storage: storage存储类型,默认SessionStorage(不推荐使用,因为跳转页面数据会丢失)

paths: 选择持久化的字段,可以多选,逗号分隔

import { defineStore  } from "pinia";

export const useLoginStore = defineStore({
    id: 'user',
    state: () => {
        return {
            token: '',
        }
    },
    getters: {
        getToken: (state) =>{
            return state.token
        }
    },
    actions: {
        setToken(val) {
            this.token = val
        }
    },
    //启用插件
    persist: {
        enabled: true,
        strategies: [
            {
                storage: localStorage,
                paths: ['token']
            }
        ]
    }
})

持久化token

在login.vue页面,引入user pinia,调用setToken方法将值存到pinia中

import { useLoginStore } from '@/pinia/user'

const useStore = useLoginStore()

//登陆方法
login(ruleForm).then(res => {
        useStore.setToken(res.token)
        router.push("/")
    }).finally(() => {
        loading.value = false
    })

持久化效果如下图,key是pinia的唯一id, value是一个对象,包括自已定义的token变量名 image.png

基于token判断是否登陆

在permission.js 页面,引入user pinia并调用

在user.js中定义的getToken是直接返回了token这个key的value值,所以拿到是一串字符串

注意点: useLoginStore方法在js文件中只能在方法里使用,如果在方法体外调用,会提示pinia没有激活,请注册之类的提示,并且页面会白屏

import { useLoginStore } from '@/pinia/user'

router.beforeEach((to,from,next) => {

    const useStore = useLoginStore()
    //要根据登陆后值判断
    const token = useStore.getToken
    console.log("token是否存在: ",token)

    //因值是写死的,需注释,如果值是真实的,注释去掉
    if(!token && to.path != "/login"){
        return next({ path: "/login"})
    }
    // todo 
    next()
})

请求拦截器

在axion的请求拦截器中,加上如果登陆成功,后续请求将携带token进行访问

import { useLoginStore } from '@/pinia/user'
const useStore = useLoginStore()

// axios.interceptors.request 代码内加入
const token = useStore.getToken
if (token){
    config.headers["token"] = token
}

根据token显示页面

因为登陆页在菜单中,这里做一个判断,来展示部分内容

<div v-if="!loginState">
       个人信息
</div>
<el-row class="login-page" v-if="loginState">
登陆
</el-row>
import { reactive, ref,onBeforeMount } from 'vue'

const loginState = ref(true)
//页面加载之前
onBeforeMount(() => {
    if(useStore.getToken){
        loginState.value = false
    }else{
        loginState.value = true
    }
})

效果

在持久化token之后,就可以随意关闭跳转页面了,后端token有效期多长,这段时间都不需要重复输密码了

当然也可以手动清理掉持久化token,见下图 image.png

然后刷新页面,就会重新跳到登陆页 image.png