❤ pinia的使用(Vue3系统篇八Pinia大菠萝)❤ pinia的使用(Vue3系统篇八Pinia大菠萝) 1、P
❤ pinia的使用(Vue3系统篇八Pinia大菠萝)
1、Pinia简介
简介
Pinia是什么
Pinia 是一个为 Vue 3 设计的状态管理库,vue3建议使用pinia代替vuex进行状态管理。
Pinia旨在提供简洁、强大且易于使用的 API,用于在 Vue 应用程序中管理状态。它提供了一种基于 Vue 3 的响应式系统的方式来管理全局和局部的状态,同时也与 TypeScript 很好地集成在一起。
vue2的都知道vuex状态管理,所谓状态管理,简单来说就是一个存储数据的地方,存放在Vuex中的数据在各个组件中都能访问到,它是Vue生态中重要的组成部分。
而pinia同理也是起到状态管理的作用,但是它又不完全同于vuex,相比有如下优点:
-
Vue2和Vue3都支持,这让我们能很快上手
-
pinia中只有state、getter、action,抛弃了Vuex中的Mutation,Vuex中mutation一直都不太受待见,pinia直接抛弃。
-
pinia中action支持同步和异步
-
良好的Typescript支持,Vue3推荐使用TS来编写
-
无需再创建各个模块嵌套了,Vuex中如果数据过多,我们通常分模块来进行管理,而pinia中每个store都是独立的,互相不影响。
-
体积非常小,只有1KB左右。
-
pinia支持插件来扩展自身功能。
-
支持服务端渲染。
Pinia 关键特点
-
基于 Vue 3 的响应式系统:Pinia 利用了 Vue 3 的响应式系统,使得在应用中管理状态变得非常直观和高效。
-
使用 Vue Composition API:Pinia 鼓励开发者使用 Vue 3 的 Composition API 来定义状态和逻辑,这使得代码更清晰和可维护。
-
零依赖:Pinia 是一个轻量级的库,不依赖于其他状态管理库或类似的工具,使得它具有很高的灵活性。
-
支持 TypeScript:Pinia 提供了对 TypeScript 的内置支持,包括类型推导、接口定义和类型安全等功能,这使得使用 TypeScript 进行开发变得更加顺畅。
-
插件系统:Pinia 提供了插件系统,使得开发者可以根据项目的需要进行功能扩展和定制,例如增加中间件、开发工具等。
2、安装使用pinia
(1)安装和使用示范
yarn add pinia
3、基于Vue3如何使用pinia
(1)创建store
创建一个 store,例如 counterStore
// src/stores/counterStore.js
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++;
},
decrement() {
this.count--;
},
},
});
在需要使用 store 的组件中导入并使用它
<template>
<div>
<p>Count: {{ counterStore.count }}</p>
<button @click="counterStore.increment()">Increment</button>
<button @click="counterStore.decrement()">Decrement</button>
</div>
</template>
<script>
import { useCounterStore } from '@/stores/counterStore';
export default {
setup() {
const counterStore = useCounterStore();
return { counterStore };
},
};
</script>
(2)我的开源项目中详细使用
接下来我们就在开源项目Nexus之中把这部分的pinia使用尝试一下,并且利用pinia实现我们的登录部分
首先我们获取一下用户的权限,这部分我们需要用到一个东西,这个东西就是js-cookie,拿来存储我们的cookie信息
👉 在utils=>auth.js ,然后我们使用这个部分把token都放入Cookies部分
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
👉 在store之中我们简单封装一下user的信息,用来存储关于用户的token信息
在store=> modules=> user.js 之中简单的封装一下我们的用户登录信息
这里我们主要是对于用户的账号密码进行传递,然后传递我们的token,默认带一张我们默认的头像部分
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import defAva from '@/assets/images/defaulte_avatar.png'
const useUserStore = defineStore(
'user',
{
state: () => ({
token: getToken(),
name: '',
avatar: '',
roles: [],
permissions: []
}),
actions: {
// 登录
login(userInfo) {
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then(res => {
setToken(res.token)
this.token = res.token
resolve()
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
getInfo() {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const user = res.user
const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
this.roles = res.roles
this.permissions = res.permissions
} else {
this.roles = ['ROLE_DEFAULT']
}
this.name = user.userName
this.avatar = avatar;
resolve(res)
}).catch(error => {
reject(error)
})
})
},
// 退出系统
logOut() {
return new Promise((resolve, reject) => {
logout(this.token).then(() => {
this.token = ''
this.roles = []
this.permissions = []
removeToken()
resolve()
}).catch(error => {
reject(error)
})
})
}
}
})
export default useUserStore
接下来完善我们的登录部分
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
// 处理表单提交的函数
const handleSubmit = async (event) => {
event.preventDefault();
// 在实际应用中,这里可以发送注册请求到服务器进行用户注册
// 这里简单地假设密码和确认密码相同才能注册成功
if (form.value.username === '' || form.value.password === '') {
ElMessage.error('用户名和密码不能为空');
return;
}else{
console.log(form.value, 'form.value');
try {
const res:any = await login(form.value);
if(res.code==200){
ElMessage.success(res.message);
// 调用action的登录方法
userStore.login(loginForm.value).then(() => {
const query = route.query;
const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
if (cur !== "redirect") {
acc[cur] = query[cur];
}
return acc;
}, {});
router.push({ path: redirect.value || "/", query: otherQueryParams });
}).catch(() => {
loading.value = false;
});
}else{
ElMessage.error(res.message);
}
} catch (error) {
// console.log('获取数据详情失败,请重试!',error);
} finally {
// console.log('完!');
}
}
return;
};
这里看看我们的登录接口部分
import request from '@/utils/request.js'
// 登录方法
export function login(username, password, code, uuid) {
const data = {
username,
password,
code,
uuid
}
return request({
url: '/api/login',
headers: {
isToken: false,
repeatSubmit: false
},
method: 'post',
data: data
})
}
尝试调用一下看看
这里记得完善一下我们token部分
import { getToken } from '@/utils/auth'
权限部分记得更改一下
if (whiteList.indexOf(to.path) !== -1||getToken()) {
console.log('白名单或者token账号进入1!');
next();
}
点击登录ok!
转载自:https://juejin.cn/post/7401824176229531682