pinia初体验

vue3推出很长一段时间了,它的周边生态也越来越完善。我们在写vue2时常用vuex最状态管理,在vue3的时代尤大推荐我们用pinia做状态管理。今天我们来看看pinia的简单使用。

基础用法

安装

1
2
3
yarn add pinia
# 或者使用 npm
npm install pinia

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// main.js
import { createPinia } from 'pinia'
app.use(createPinia())

// 定义一个 Store
// src/stores/counter.ts
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
// 相当于vuex中的state
const count = ref(0)
// 相当于vuex中的getters
const doubleCount = computed(() => count.value * 2)
// 这就是vuex中的actions了
function increment() {
count.value++
}
return { count, doubleCount, increment }
})

// 在组件中使用
// src/App.vue
<template>
<div>{{ counter.count }}</div>
<button @click="handleIncrement ">增加</button>
<button @click="handleDecrement">减少</button>
</template>

<script setup lang="ts">
import { useCounterStore } from "@/stores/counter";
const counter = useCounterStore();

const handleIncrement = () => {
counter.increment();
};

const handleDecrement = () => {
counter.$patch({ count: counter.count - 1 });
};
</script>

// 在组件外使用
// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import { useCounterStore } from "@/stores/counter";

const router = createRouter({
// ...
})

router.beforeEach((to, from, next) => {
const counter = useCounterStore();
console.log(counter.count); // 0
next()
})
export default router

一些语法

解构

使用传统的方式将属性从store中解构出来,虽然可以获取到值,但是不具有响应式。

1
2
const { count, doubleCount } = counter;
console.log(count, doubleCount); // 始终是 0 0

为了从store中解构属性的时候保持其响应式,我们可以使用pinia提供的storeToRefs函数。

1
2
3
4
5
6
import { useCounterStore } from "@/stores/counter";
import { storeToRefs } from "pinia";

const counter = useCounterStore();
const { count, doubleCount } = storeToRefs(counter);
console.log(count, doubleCount); // Ref<0> ComputedRef<0>

或者使用vue提供的toRefs函数。

1
2
3
4
5
6
import { useCounterStore } from "@/stores/counter";
import { toRefs } from "vue";

const counter = useCounterStore();
const { count, doubleCount } = toRefs(counter);
console.log(count, doubleCount); // Ref<0> Ref<0>

批量修改store中数据

除了用 counter.count++ 直接改变 store,还可以调用 $patch 方法。

1
2
3
4
counter.$patch({
name: "666",
count: 888,
});

不过,用这种语法的话,向数组中添加、移除一个元素操作很难实现,因此,$patch 方法也接受一个函数来组合这种难以用补丁对象实现的变更。

1
2
3
4
counter.$patch((state) => {
state.count = 666;
state.name = "aksdkljkl";
});

pinia vs vuex

  • pinia拥有更简洁的语法,取消了mutations,只有三个概念,state、getter和 action,相当于组件中的 data、 computed 和 methods

pinia初体验
https://xypecho.github.io/2023/02/22/pinia初体验/
作者
很青的青蛙
发布于
2023年2月22日
许可协议