首先贴出官网地址:开始 | 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爆红,但是不影响使用