pinia状态管理 用法
Pinia是一个用于vue的状态管理库,类似于vuex,是vue的另一种状态管理工具。
Pinia 是 Vue 的存储库,它允许跨组件/页面共享状态。实际上,Pinia就是Vuex的升级版,官网也说过,为了尊重原作者,所以取名pinia,而没有取名Vuex,所以大家可以直接将Pinia比作为vue3的vuex。 很多人也将Pinia称为vuex5。
在Pinia中,每个store都是单独存在,一同进行状态管理。
一:pinia与vuex的区别
与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的规范,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。
1.mutations 不再存在。
2.无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。
3.不再需要注入、导入函数、调用函数、享受自动完成功能!
4.无需动态添加 Store,默认情况下它们都是动态的
5.不再有 modules 的嵌套结构
二:基本配置和使用
1、安装
可以用自己常用的包管理器安装,例如:
pnpm install pinia yarn add pinia npm install --save pinia
2、 基本使用
①:创建pinia实例并挂载
在main.ts中:
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
// 引用
import {createPinia } from 'pinia'
// 创建Pinia实例
const Pinia = createPinia()
// 挂载pinia
createApp(App).use(Pinia).mount('#app')
②: 配置状态管理专用文件,在根目录下创建一个store文件,并新建一个index.ts文件
③:通过import将下载好的pinia引入到index.ts中并导出 并使用defineStore创建store对象
import { defineStore } from 'pinia'//
// 第一个参数是应用程序中 store 的唯一 id
export const useStore = defineStore('main', {})
三:pinia基础特性
1、state
创建stateimport { defineStore } from 'pinia'// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
export const useStore = defineStore('main', {state:()=>{//创建状态return {text:"我是pinia的一个状态变量"}}
})
组件中使用<template><div><!-- 3.使用 -->我是测试pinia的组件--{{store.text}}</div>
</template><script lang="ts" setup>
// 1.引用
import 名字 from "你pinia编写的文件"
// 2.创建
let store=名字()
</script><style></style>
(1)默认情况下,通过 store 实例访问 state,可以直接读取和写入,
如:@click="store.count++"
(2)通过 store.$reset() 方法可以将 state 重置为初始值。
(3)除了直接通过 store 修改 state,还可以通过 store.$patch() 方法提交多个更改。
(4)可以通过 store.$subscribe() 订阅 State 的变化,在 patches 修改之后订阅只会触发一次。默认情况下,订阅绑定到添加它的组件,当组件卸载时,它们将自动删除,也可以配置将其保留。
2、getters
(1)Getters 属性的值是一个函数,接受 state 为第一个参数,目的是鼓励使用箭头函数。 (2)非箭头函数会绑定 this,建议仅在需要获取整个 store 实例的场景使用,且需要显式定义函数返回类型。
import { defineStore } from 'pinia'export const useStoreb = defineStore('mainb', {state:()=>{return {text:"abcdefg"}},actions:{},getters:{newtext(){ return this.text.toUpperCase()}}
})
3、actions--修改
修改方式一: 组件内创建触发。
① store.你在pinia中actions中创建的修改函数
<template><div> 我是测试pinia的组件--{{store.text}}<button @click="update()">点我修改</button></div>
</template><script lang="ts" setup>
import {useStore} from "../store/index"
let store=useStore()let update=()=>{// 调用修改方法 store.你在pinia中actions中创建的修改函数store.TEXT_UPDATE()
}
</script><style></style>
② pinia中创建修改方法
import { defineStore } from 'pinia'export const useStore = defineStore('main', {state:()=>{return {text:"我是pinia的一个状态变量"}},actions:{TEXT_UPDATE(){//修改方法this.text="我变了"}}
})
修改方式二:$patch
//在组件内调用$parch 便可直接修改数据
let update=()=>{store.$patch({//你要修改state的数据: 你要修改的value值text:"我是$patch直接修改"})
}//方式2
let update=()=>{store.$patch((state)=>{console.log(state)state.text="你又被改了"})
}
store是一个对象,在数据很多的情况下,那么我们可以使用解构。但是使用解构之后,数据会失去响应式,这个时候我们可以使用 storeToRefs来保持数据的响应式。
<template><div>我是测试pinia的组件--{{text}}<button @click="update()">点我修改</button></div>
</template><script lang="ts" setup>
import {useStore} from "../store/index"
import {storeToRefs} from "pinia"
let store=useStore()// 解构取值
// let {text}=store
// storeToRefs 让数据快去取出 并且不丢失响应式
let {text}=storeToRefs(store)
let update=()=>{// 调用修改方法 store.你在pinia中actions中创建的修改函数store.updatetext()
}
</script>
4、action--处理异步操作
在pinia中acition不但能处理同步操作 同样也可以处理异步操作
使用方式和vuex一致
在组件中:
<template><div> 我是测试pinia的组件--{{store.text}}<button @click="demoAxios()">点我获取异步数据</button> </div>
</template><script lang="ts" setup>import {useStore} from "../store/index"
let store=useStore()let demoAxios=()=>{store.link()
}</script>
在pinia中:
import { defineStore } from 'pinia'
import $http from "axios"
export const useStore = defineStore('main', {state:()=>{return {text:"我是pinia的一个状态变量"}},actions:{async link(){try {let data= await $http({url:"",method:"get"})//需要的操作} catch (error) {console.log("失败")}}}
})
5、$reset--重置数据
意思就是让数据恢复为state的初始值
<template><div> 我是测试pinia的组件--{{store.text}}<button @click="update()">点我修改</button><button @click="reset()">点我恢复初始值</button> </div>
</template>
<script lang="ts" setup>
import {useStore} from "../store/index"
let store=useStore()
let update=()=>{store.updatetext()
}
let reset=()=>{// $resetstore.$reset()
}
</script>
6、$subscribe--监听数据修改
$subscribe 监听pinia数据修改 当数据改变了 那么subscribe也会触发
<template><div> 我是测试pinia的组件--{{store.text}}<button @click="update()">点我修改</button> </div>
</template>
<script lang="ts" setup>
import {useStore} from "../store/index"
let store=useStore()
let update=()=>{store.updatetext()
}
// 监听store数据修改
let sub=store.$subscribe((params,state)=>{console.log("params",params);//修改的操作console.log("state",state);//修改后的数据
})
</script>
7、模块化
pinia中取消了modules。
pinia中定义模块,只需要定义多个store即可。
因为pinia没有单一数据源这个概念,在其中可以定义多个store对象
<template><div><h1> 第一个store:{{storeone.text}}</h1><h1> 第二个store:{{storetwo.text}}</h1> </div>
</template><script lang="ts" setup>
// 引用第一个store
import {useStore} from "../store/index"
// 引用第2个store
import {useStoreb} from "../store/indexb"
let storeone=useStore()let storetwo=useStoreb()
</script>
四:pinia优势
综上,pinia的优点已经很明显了
- ts兼容性好 、不需要命名空间,可以创建多个store、mutation删掉了
- pinia只具备以下几个属性,状态、计算属性、动作
- pinia大小也会更小巧一些