一、pinia的简单使用
vuex和pinia的区别
参考网址:[Vuex] Vuex 5 by kiaking · Pull Request #271 · vuejs/rfcs · GitHub
1.pinia没有mutations,只有:state、getters、actions
2.pinia分模块不需要models(之前vuex分模块需要models)
3.TS支持的很好
4.pinia体积更小(性能更好)
5.pinia可以直接修改state数据
pinia的使用
1. npm i pinia
2. 在main.js中进行引用
import { createPinia } from 'pinia';
export const app = createApp(App)
app.use(createPinia());
3.在src下store文件下新建index.js
import { defineStore } from 'pinia' const userStore = defineStore({ id: 'useStore',//id必须唯一 state: () => { return { token: '123', userInfo: null, } }, getters:{ }, actions: { setToken(token) { this.token = token }, }, }) export default userStore
4.在组件中使用pinia
a.不结构state,通过pinia的actions去更改state
<template> <div class="A"> <h1>A组件</h1> <div>{{ store.token }}</div> <div> 姓名:{{store.userInfo.name}} 年龄:{{ store.userInfo.age }} </div> <el-button type="success" @click="changeName()">修改名称</el-button> </div> </template> <script setup> import { userStore } from '../store/index.js'; const store = userStore() let {setName} = store let changeName =()=>{ setName('李四') } </script> <style lang="scss"> .A{ font-size: 30px; margin: 0 auto; text-align: center; .el-button{ font-size: 30px; padding: 10px; height: 50px; } } </style>
b.结构state时候要使用storeToRefs去让它变成响应式数据从而改变
<template> <div class="A"> <h1>A组件</h1> <div>{{ token }}</div> <div> 姓名:{{userInfo.name}} 年龄:{{ userInfo.age }} </div> <el-button type="success" @click="changeName()">修改名称</el-button> </div> </template> <script setup> import { storeToRefs } from 'pinia'; import { userStore } from '../store/index.js'; const store = userStore() let {token,userInfo,setName} = storeToRefs(store) let changeName =()=>{ // userInfo.value.name='李四' //$patch批量修改 store.$patch(state=>{ console.log(state); state.userInfo.age=12 state.userInfo.name='李四' }) } </script> <style lang="scss"> .A{ font-size: 30px; margin: 0 auto; text-align: center; .el-button{ font-size: 30px; padding: 10px; height: 50px; } } </style>
c.pinia的getters
import { defineStore } from 'pinia' export const userStore = defineStore({ id: 'useStore', state: () => { return { token: 'gdsiuafoi1234_key', userInfo: { name:"张三", age:18 }, } }, getters:{ //箭头函数--接受参数 getNameInfo:state=>{ //箭头函数中this不是store return (param)=>`${state.userInfo.name}今年已经${state.userInfo.age}岁了${param}` }, getNameInfo1(state){ return function(param){ return `2.${state.userInfo.name}今年已经${state.userInfo.age}岁了${param}` } } } })
<template> <div class="A"> <h1>A组件</h1> <div>{{ token }}</div> <div> 姓名:{{userInfo.name}} 年龄:{{ userInfo.age }} </div> <div> {{getNameInfo('是吗?')}} </div> <div> {{getNameInfo1(',对的')}} </div> <el-button type="success" @click="changeName()">修改名称</el-button> </div> </template> <script setup> import { storeToRefs } from 'pinia'; import { userStore } from '../store/index.js'; const store = userStore() let {token,userInfo,setName,getNameInfo,getNameInfo1} = storeToRefs(store) </script> <style lang="scss"> .A{ font-size: 30px; margin: 0 auto; text-align: center; .el-button{ font-size: 30px; padding: 10px; height: 50px; } } </style>
二、pinia的分模块化
在store文件下通过不同的js进行分模块拆分
user.js
import { defineStore } from 'pinia' export const user = defineStore({ id: 'user', state: () => { return { token: 'gdsiuafoi1234_key', userInfo: { name:"张三", age:18 }, } }, getters:{ //箭头函数--接受参数 getNameInfo:state=>{ //箭头函数中this不是store return (param)=>`${state.userInfo.name}今年已经${state.userInfo.age}岁了${param}` }, getNameInfo1(state){ return function(param){ return `2.${state.userInfo.name}今年已经${state.userInfo.age}岁了${param}` } } }, actions: { setToken(token) { this.token = token }, setName(name){ this.userInfo.name=name } }, })
shop.js
import { defineStore } from 'pinia' export const shop = defineStore({ id: 'shop', state: () => ({ shopList:['鞋子','衣服'] }), getters:{ }, actions: { }, })
使用:
<template> <div class="A"> <h1>A组件</h1> <div> {{userInfo.name}} {{userInfo.age}} </div> <div> {{getNameInfo('是吗?')}} </div> <el-button type="success" @click="changeName()">修改名称</el-button> <div> shopStore </div> <div v-for="(el,index) in shopList" :key="index"> {{el}} </div> </div> </template> <script setup> import { storeToRefs } from 'pinia'; import { user } from '../store/user.js'; import {shop} from '../store/shop.js' const userStore = user() const shopStore = shop() console.log(userStore); let { userInfo,getNameInfo } = storeToRefs(userStore) let { shopList } = storeToRefs(shopStore) const changeName = ()=>{ // userInfo.value.name='李四' userStore.setName('李四') } </script> <style lang="scss"> .A{ font-size: 30px; margin: 0 auto; text-align: center; .el-button{ font-size: 30px; padding: 10px; height: 50px; } } </style>
三、pinia的持久化存储
1.下载插件依赖:npm i pinia-plugin-persist -save
2.在store文件下新建index.js文件,再在main.js中引入并使用
import store from './store/index.js'; app.use(store);
idnex.js
import { createPinia } from 'pinia' //引入持久化插件 import piniaPluginPersist from 'pinia-plugin-persist' const store = createPinia() //使用插件 store.use(piniaPluginPersist) export default store
在模块化中使用(user)
persist:{ //是否启用持久化存储,不进行配置默认存储为session,刷新页面持久化了但是重新开启一个页面还是开始的值 enabled:true }
a.基础使用
创建 Store 时,将
persist
选项设置为true,
整个 Store 将使用默认持久化配置保存。默认持久化配置
使用 session进行存储
store.$id作为 storage 默认的 key
使用 JSON.stringify / JSON.parse进行序列化/反序列化
整个 state 默认将被持久发
b.高级使用
三个常用属性:
key:存储名称。
storage:存储方式。 sessionStorage 、localStorage
path:用于指定 state 中哪些数据需要被持久化。
[]
表示不持久化任何状态,undefined
或null
表示持久化整个 state。import { defineStore } from 'pinia' export const user = defineStore({ id: 'user', state: () => { return { token: 'gdsiuafoi1234_key', userInfo: { name:"张三", age:18 }, } }, getters:{ //箭头函数--接受参数 getNameInfo:state=>{ //箭头函数中this不是store return (param)=>`${state.userInfo.name}今年已经${state.userInfo.age}岁了${param}` }, getNameInfo1(state){ return function(param){ return `2.${state.userInfo.name}今年已经${state.userInfo.age}岁了${param}` } } }, actions: { setToken(token) { this.token = token }, setName(name){ this.userInfo.name=name } }, persist:{ //是否启用持久化存储,不进行配置默认存储为session,刷新页面持久化了但是重新开启一个页面还是开始的值 enabled:true, strategies:[{ key:'user_info', storage:localStorage, paths:['userInfo'] }] } })