前言
时间过得真快,距离 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())
}
}
})
结语
我是一名前端程序员,但不止于前端,如果有大佬觉得文章哪里有些欠妥,欢迎评论区一起讨论,一起学习~,最后,再次感谢你能看到这里。