首先贴出官网地址:开始 | Pinia
pinia作为Vue3项目中常用的状态管理工具,正逐渐取代vuex,现从0到1自己搭建pinia仓库。
首先,安装pinia,使用包管理器工具(npm,pnpm,yarn,Bun等都可以)
安装成功后,就会在package.json中找到
然后就是在入口文件中使用(我是用的是vite创建的项目,所以入口文件就是main.ts):
创建pinia实例并使用,相关的创建代码中,移到了Store文件夹中。
具体内容如下:
import {createPinia} from 'pinia'//创建大仓库let pinia=createPinia()//导出仓库
export default pinia;
然后需要在入口文件中使用:
这样就建立了一个空的仓库 ,然后我们还需要定义一个Store,在Vuex中对应的state,getter,action中,都会在Store中进行定义。
定义Store是用defineStore函数定义的
然后我自己新建一个空文件testStore.ts
内容如下:
import { defineStore } from "pinia";let useTestStore=defineStore("test",{state:()=>{return {name:"test",count:10}},getters: {doubleCount: (state) => state.count * 2,},actions: {increment() {this.count++},},
})export default useTestStore;
这里需要注意几个点:首先,定义Store一般需要以use开头,第一个参数是你的应用中 Store 的唯一 ID。第二个参数就是仓库的配置项,state 是 store 的数据 (data),getters 是 store 的计算属性 (computed),而 actions 则是方法 (methods)。上面的写法是选项式写法,写过vuex的可能会对此写法更加的熟悉,但是pinia还有另一种组合式写法,习惯使用组合式API的可能更喜欢这种写法。
将上面的代码转换成组合式写法(setup)
import { defineStore } from "pinia";
import { ref,computed } from "vue";
let useTestStore=defineStore("test",()=>{const count=ref(10)const name=ref('test')const doubleCount=computed(()=>count.value*2)//注意,action中的方法不要写成箭头函数function increment() {count.value++;}return {count,name,doubleCount,increment}
})export default useTestStore;
在组合式写法中,state中的属性需要使用ref定义,getters中的计算属性就直接使用computed()进行使用即可,而actions则在下面直接进行函数(普通函数)定义即可。
这样我们的仓库就定义好了,我们需要再组件中进行使用。
这里是再项目中使用了路由,所以需要根据指定路径进行跳转,在控制台中,我们可以看到打印的信息,我们就可以直接使用插值语法直接渲染在页面中。
然后使用按钮修改count的值,看对应的getter和action中定义的方法。
全部代码如下:
<template><div>{{ testStore.name }}---{{ testStore.count }}<el-button type="primary" size="default" @click="handler">点我修改count</el-button></div>
</template><script setup lang="ts">
import {ref,reactive} from 'vue'
import useTestStore from '../../store/testStore';const testStore = useTestStore()console.log(testStore);const handler=()=>[testStore.increment(),console.log(testStore.doubleCount)
]
</script><style scoped lang="scss"></style>
这样我们就使用了仓库中的方法和计算属性,以及仓库中存储的state。当然了,同步和异步的方法都可以直接写在仓库中,因为pinia中没有mutation,所以一个action中可以书写同步和异步的方法,大大简化了状态更新流程。
当然了仓库,可以建立多个,我们可以建立多个ts文件来创建不同功能的Store,用到的时候需要那个仓库就进行引入即可。
还有就是Store可以嵌套,就是在定义一个Store时,可以使用领一个Store中的数据,代码演示如下:
/** @Author: RealRoad* @Date: 2024-10-14 15:50:02* @LastEditors: Do not edit* @LastEditTime: 2024-10-14 16:00:44* @Description: * @FilePath: \project_10_08\vite-project\src\store\testStore.ts*/
import { defineStore } from "pinia";
import { ref,computed } from "vue";
let useTest2Store=defineStore("test2",()=>{const count=ref(10)const name=ref('test')const huawei=ref('遥遥领先')const doubleCount=computed(()=>count.value*2)//注意,action中的方法不要写成箭头函数function increment() {count.value++;}return {count,name,doubleCount,increment,huawei}
})export default useTest2Store;
注意,这里的仓库名不要和领一个仓库名重名!!!
仓库定义如下:
/** @Author: RealRoad* @Date: 2024-10-14 15:50:02* @LastEditors: Do not edit* @LastEditTime: 2024-10-14 16:00:44* @Description: * @FilePath: \project_10_08\vite-project\src\store\testStore.ts*/
import { defineStore } from "pinia";
import { ref,computed } from "vue";
import useTest2Store from "./testStore2";
let useTestStore=defineStore("test",()=>{const count=ref(10)const name=ref('test')const iphone=useTest2Store()const doubleCount=computed(()=>count.value*2)//注意,action中的方法不要写成箭头函数function increment() {count.value++;}return {count,name,doubleCount,increment,iphone:iphone.huawei}
})export default useTestStore;
界面直接使用:
给pinia添加插件
就是在定义大仓库导出大仓库之前进行插件定义,然后使用pinia实例进行使用该插件,就相当于默认给pinia添加了一些属性和方法,这样,无论是哪个Store,都可以直接使用这些插件。
那么pinia实例的定义如下:
import {createPinia} from 'pinia'//创建大仓库
//创建时给pinia仓库一个默认的属性值
function piniaPlugin(){return {default:'Hello MEZ!!'}
}
let pinia=createPinia()
pinia.use(piniaPlugin)//导出仓库
export default pinia;
然后我们在使用仓库的时候,就可以直接使用。
虽然ts爆红,但是不影响使用