1. 安装pinia
Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。效果与vuex相同
npm install pinia
2. 创建store
文件夹,并在此文件夹中创建index.ts
文件
3. 编码存储token
的方法
(1)
isAuthenticated:false; // isAuthenticated 判断用户是否登录,默认为false,即未登录,登录之后修改为true
user:{} //存储token解析之后的内容 token解析之后是对象
// stores/counter.js 在pinia中,getters和state中不能使用相同的名字,但是vuex中可以使用相同的名字
import { defineStore } from 'pinia'
//存储token 和 解析token 的用户
export const useAuthStore = defineStore('auth', {
state: () => { //管理俩个状态 一个是是否登录成功即token是否存在,二是解析的token里面所包含的数据
return { isAuthenticated: false, user: {} }
},
// 也可以定义为
// state: () => ({ count: 0 })
getters: { //通过getters对状态state进行获取
getAuthenticated: (state) => state.isAuthenticated,
getUser: (state) => state.user
},
actions: {
setAuth(isAuth: boolean) {//修改当前登录的状态
if (isAuth) {
this.isAuthenticated = isAuth; //在pinia中this指代state
} else {
this.isAuthenticated = false;
}
},
setUser(user: any) { //解析的用户
if (user) {
this.user = user;
} else {
this.user = {};
}
}
},
})
PS:pinia
中,采用this
替代state
,并且pinia
中没有mutation
API,只有actions
4. 在登录组件使用,调用方法,存储token
import { useAuthStore } from '../store';
import jwt_decode from 'jwt-decode'//解析token
const store = useAuthStore();
// 表单提交
const handleSubmit = (formEl: FormInstance | undefined) => {
if (!formEl) return; //判断formEl是否为空,为空
formEl.validate(async (valid: boolean) => {
if (valid) { //如果校验成功 请求数据
// console.log('submit!')
// const {data} = await axios.post("http://localhost:3000/users",registerUser.value);
const { data: { success, token } } = await axios.post("/api/users/login", loginUser.value);
// console.log(data)
// 登录成功,储存token
if (success && token) { //如果success为真,并且token有内容
localStorage.setItem("token", token);
//解析token
const decode = jwt_decode(token);
console.log(decode);//decode是一个对象
//存储token解析的内容 以及修改登录的状态
store.setAuth(!!decode) //由于decode是对象,所以对他取反再取反,双非就变成了布尔类型
store.setUser(decode)
// @ts-ignore
ElMessage({
message: '用户登录成功!!!',
type: 'success',
})
router.push("/")
}
} else {
// console.log('error submit!')
// @ts-ignore
ElMessage({
message: '该账号已被注册',
type: 'warning',
})
return false
}
})
console.log(loginUser.value);
}
5. 为了防止页面刷新之后,通过store存储的token内容会丢失,我们需要在App组件中,也进行存储
<script setup lang="ts">
// import Home from './views/Home.vue';
import { watchEffect } from 'vue'; //watchEffect一进来就触发
import jwt_decode from 'jwt-decode'
import {useAuthStore} from './store'
const store = useAuthStore();
// 页面刷新,vuex中存储的状态依然存在
watchEffect(()=>{ //watchEffect页面一刷新,方法立即被调用
if(localStorage.token){
const decode = jwt_decode(localStorage.token);
store.setAuth(!!decode);
store.setUser(decode);
}
})
</script>
注意:可以通过vue的开发者工具dev-tools在浏览器的控制台查看 存储的内容