storeToRefs

在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
<template>
<div>
origin: {{ Test.current }} --- {{ Test.name }}
<br>
<!-- 失去了响应式 -->
now: {{ current }} --- {{ name }}
<br>
<button @click="change">change</button>
</div>
</template>

<script setup lang="ts">
import { useTestStore } from "./store"

const Test = useTestStore()

const { current, name } = Test

const change = ()=> {
console.log(current, name)
Test.current++
Test.name+="yajue"
}
</script>

如果需要解构,应该使用storeToRefs包裹:

1
2
3
4
5
6
import { useTestStore } from "./store"
// 类似Vue3的toRefs
import { storeToRefs } from "pinia"

const Test = useTestStore()
const { current, name } = storeToRefs(Test)

源码

和toRefs类似。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function storeToRefs(store) {
// See https://github.com/vuejs/pinia/issues/852
// It's easier to just use toRefs() even if it includes more stuff
if (isVue2) {
// @ts-expect-error: toRefs include methods and others
return toRefs(store);
}
else {
// store是个proxy对象,通过toRaw解出原始对象,防止重复引用
store = toRaw(store);
const refs = {};
// 遍历每个键值,包裹为响应式
for (const key in store) {
const value = store[key];
if (isRef(value) || isReactive(value)) {
// @ts-expect-error: the key is state or getter
refs[key] =
// ---
toRef(store, key);
}
}
return refs;
}
}