一、 pinia特点
- window.location.href = “https://blog.csdn.net/2301_76459194?spm=1011.2266.3001.5343”
- 兼容vue2和vue3版本
- 删除mutations
不能与vuex混用(注意避坑)
- 支持插件扩展功能
- 支持模块热更新无需加载页面可以修改容器,可以保持任何现有的状态
- 更完美TS支持
- 支持服务端渲染
二、 基本使用及容器组成
安装命令
npm install pinia
在main.js中引入pinia并创建容器挂载到根实例上
// 引入挂载
import { createPinia } from 'pinia'
const pinia = createPinia()
createApp(App).use(pinia).mount('#app')
容器基本组成
- 创建store/index.js,引入pinia
defineStore( )
方法的第一个参数:相当于为容器起一个名字。注意:这里的名字必须唯一
。这个是官方特别说明的一个事情。defineStore( )
方法的第二个参数:可以简单理解为一个配置对象,里边是对容器仓库的配置说明。
//引入
import { defineStore } from "pinia"
// 定义容器
export const useMain = defineStore('useStore', {
// 存储全局状态
// 必须是箭头函数: 为了在服务器端渲染的时候避免交叉请求导致数据状态污染
state: () => {
return {
count: 0,
list: [1, 2, 3, 4 ]
}
},
//用来封装计算属性,有缓存功能,类似于computed
getters: {
},
//编辑业务逻辑 类似于methods
actions: {
}
})
二、 属性详解
2.1 state
- 存储全局状态类似于组件中的data
- 定义数据,可在任意文件中引用修改
state: () => {
return {
count: 0,
list: [ 1, 2, 3 ]
}
}
state页面使用
//引入
import { useMain } from '@/store/index.js'
const useStoreMain = useMain()
//使用
<p>{{ useStoreMain.count }}</p>
简单的数据修改或逻辑可以直接在调用的页面进行
``
<button @click="useLeStore.count++">count++</button>
<button @click="useLeStore.list.push('le')">list-push</button>
- 如果我们批量更改数据建议使用
$patch()
方法,可以优化性能
<button @click="changeMultiple">修改多个</button>
const changeMultiple = () => {
useLeStore.$patch((state) => {
console.log(state);
state.count = 100;
state.list = ["le", "lele"];
console.log(state);
});
};
2.2 getters
- 封装计算属性,有缓存功能,类似于computed,
- pinia中的getters只是在幕后做计算,不能传递任何参数,但是可以使用getters返回一个函数接受任何参数
- 这里需要传入state才能拿到数据,可以直接使用state和this效果是一样的
- 和计算属性一样的是你可以写很多getters通过this来直接访问,具体依据官网文档
getters: {
doubleCount: (state) => state.count * 2,
doubleCountPlusOne() {
return this.count + 1
}
}
getters页面使用
//引入
import { useMain } from '@/store/index.js'
const useStoreMain = useMain()
//使用
<p>{{ useStoreMain.getNum }}</p>
2.3 actions
- 在这里我们获取state里数据是不需要传入,可以直接使用
this.xxx
actions: {
addCount() {
this.count++
}
}
- actions方法可以互相调用直接使用this
例如下面的情况:
//引入
import { defineStore } from "pinia"
// 定义容器
export const leStore = defineStore('leStore', {
// 存储全局状态
// 必须是箭头函数: 为了在服务器端渲染的时候避免交叉请求导致数据状态污染
state: () => {
return {
count: 0,
list: [1, 2, 3, 4]
}
},
//用来封装计算属性,有缓存功能,类似于computed
getters: {
doubleCount: (state) => state.count * 2,
},
//编辑业务逻辑,类似于methods
actions: {
addCount() {
this.count++
},
addList() {
this.addCount()
this.list.push({ count: this.count, doubleCount: this.doubleCount })
console.log(this.list);
},
}
})
三、页面使用
state数据使用
- 可以直接使用,也可以直接结构出想要的数据,但是数据会出现
无法实现响应式问题
- 官方使用的API
storeToRefs
使state数据生成响应式 - 引用官方API
storeToRef
作用就是把结构的数据使用ref做代理 页面引入
// 引入store
import { useMain } from '@/store/index.js'
const useStoreMain = useMain()
直接使用
<template>
<div class="greetings">
<h1 class="green">{{ useStoreMain.count }}</h1>
</div>
</template>
数据解构
//引入storeToRefs
import { storeToRefs } from 'pinia'
// 直接结构后数据不为响应式
// const { count } = useStoreMain;
// 使用storeToRefs()结构,数据为响应式
const { count } = storeToRefs(useStoreMain);
数据解构-页面使用
<template>
<div class="greetings">
<h1 class="green">{{ count }}</h1>
<button @click="count++">未解构按钮</button>
<button @click="useStoreMain.count++">已解构按钮</button>
</div>
</template>
getters数据使用
略...
getters与state使用同理,不做过多演示
actions方法使用
actions: {
addCount(e) {
this.count += e
console.log(this.count);
},
}
页面调用
<button @click="changeCount">修改Count</button>
import { leStore } from "../store/leStore.js";
const useLeStore = leStore();
const changeCount = () => {
useLeStore.addCount(10)
};
四、持久化存储
npm i pinia-plugin-persist --save --include=dev
// 或者使用 yarn 安装
yarn add pinia-plugin-persist
- 安装完成之后,我们可以在
main.js 或者 main.ts 中引入
特别注意:固化插件是 pinia.use 并不是 app.use
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia';
const app = createApp(App);
// 下面是我们安装的固化插件。
import piniaPersist from 'pinia-plugin-persist'
const pinia = createPinia();
// 特别注意:固化插件是 pinia.use 并不是 app.use
pinia.use(piniaPersist);
app.use(pinia);
app.mount('#app')
持久化模块使用代码及注释详解具体如下:
import { defineStore } from 'pinia';
export const useStore = defineStore('main', {
state:()=>{
return {
count: 10,
num: 20
}
},
getters:{
},
actions:{
countAdd(){
this.count++;
}
},
//固化插件
persist: {
//开启存储
enabled: true,
// 指定存储的位置以及存储的变量都有哪些,该属性可以不写
//在不写的情况下,默认存储到 sessionStorage 里面,默认存储 state 里面的所有数据。
strategies: [
// storage 指定存储的位置,可以是 sessionStorage 或者 localStorage
// paths 是一个数组,如果只写了count 就会只存储 count 变量,当然也可以写多个。
{ storage: localStorage, paths: ["count"] },
]
},
})
*本篇的所有使用方法都可以在多个容器或多个组件之间互相引入调用,具体用法可依照业务场景自行扩展