前言
时间过得真快,距离 Vue3 发布已经 快三年 了,相信很多开发 Vue2 的小伙伴,都使用过 Vuex 这个依赖,它可以帮我们管理项目中的所有 数据,我称它为 数据仓库,在 Vue3 时代,我们潜规则式的摒弃了 Vuex,转而替代的是 Pinia,至于为什么使用它,我们稍后来谈。
介绍
正如前言所说,在 Vue3 时代,我们使用 Pinia 作为我们的数据仓库,是因为 Vue3 建议我们使用 Composition API 代替之前的 Options API,而 Pinia 与之完美的融合
- 使用
pinia作为数据仓库,可以很方便的在多个组件/页面中共用同一个变量 - 对
TypeScript的支持更加友好 - 可以在不重载页面的前提下修改仓库数据,且能实时响应在页面
与Vuex对比
- 抛弃了
mutations的操作 - 对
TypeScript的支持更加友好 - 抛弃了
module,store目录下的所有.ts/.js文件均是一个pinia模块 - 自动导入注册
你可以查看这里,官方对 pinia 和 vuex 的对比:
image.png
如何使用
安装引入
要想使用 pinia, 首先需要安装对应依赖:
npm i pinia
然后在 main.js 中引入并使用
// main.js中引入
// ...
const app = createApp(App);
// vue使用pinia
import { createPinia } from "pinia"
app.use(createPinia());
定义store
在 src/store 目录下新建 .js/.ts 文件,一个文件即是一个 store,通过 defineStore 来定义仓库
- 第一个参数为一个
唯一标识 - 第二个参数为一个
option,option中有state、getters、actions三个字段,分别表示 指代这个仓库的数据、计算属性、方法
import { defineStore } from 'pinia';
export const demoStore = defineStore('demo', {
state: () => {
return {
// 所有这些属性都将自动推断其类型
counter: 0,
mobile:"13111111111"
}
},
getters:{},
actions:{}
})
渲染state
接下来我们在 页面 渲染 state:
<script setup>
// 引入定义的store
import { demoStore } from '@/store/demo';
const store = demoStore();
</script>
<template>
<div>{{ store.counter }}</div>
</template>
如果我们想直接渲染 counter 可以通过 storeToRefs 处理一下:
<script setup>
// 引入定义的store
import { demoStore } from '@/store/demo';
// 引入storeToRefs函数,使得解构store仍具有响应式特性
import { storeToRefs } from "pinia";
const store = demoStore();
const { counter } = storeToRefs(store);
</script>
<template>
<div>{{ counter }}</div>
</template>
修改state
修改 state 有四种方式,这里挨个来介绍一番:
方法一:直接修改
通过点击事件触发该 add 方法,直接操作 store.counter
const add = () => store.counter ++
方法二:$patch传递参数
通过点击事件触发该 add方法,通过 store.$patch 进行修改,参数是个 对象
const add = () => {
store.$patch({
count:store.counter + 2,
})
};
方法三:$patch传递方法
通过点击事件触发该 add方法,通过 store.$patch 进行修改,参数是个 回调函数,可以在回调函数中处理
const add = () => {
store.$patch(state => {
state.counter += 10
})
};
方法四:actions
在 src/store/demo.ts 文件中的 actions 中定义 add 方法:
import { defineStore } from 'pinia';
export const demoStore = defineStore('demo', {
state: () => {
return {
// 所有这些属性都将自动推断其类型
counter: 0,
}
},
getters:{},
actions:{
add(n){
this.counter = n;
},
}
})
在页面中通过调用 store.add 方法来修改:
const add = () => store.add(10)
Getters的使用
getters 与 vue 中的 computed 类似,提供计算属性:
// store/demo.ts
// ...
export const demoStore = defineStore('demo', {
state: () => {
return {
mobile:"13111111111"
}
},
getters:{
mobileHidden:(state) => {
return state.mobile.replace(/(\d{3})\d{4}(\d{4})/g,`$1****$2`);
}
},
actions:{}
})
在页面中使用同 state。
store互调
假设我们有多个 store,他们之间也是可以互相调用的,需要先将 testStore 调用实例化,然后读取里面方法:
// store/demo.ts
import { defineStore } from 'pinia';
// 引入第二个store
import { testStore } from './test';
export const demoStore = defineStore('demo', {
state: () => {
return {}
},
getters:{},
actions:{
getList(){
const store2 = testStore();
console.log(store2.fn())
}
}
})
结语
我是一名前端程序员,但不止于前端,如果有大佬觉得文章哪里有些欠妥,欢迎评论区一起讨论,一起学习~,最后,再次感谢你能看到这里。