Pinia解构容器数据不是响应式数据的处理方法
什么是解构容器数据?
我们在state中定义了两个状态count
和foo
,如下:
export const useMainStore = defineStore('main', {
state: () => {
return {
count: 100,
foo: 'bar'
}
},
getters: {
},
actions: {
}
一般我们在组件中使用是引入容器之后,通过容器名来调用状态,如下:
<template>
<p>{{ useStore.count }}</p>
<p>{{ useStore.foo }}</p>
</template>
<script lang="ts" setup>
import { useMainStore } from "../store"
const useStore = useMainStore()
console.log(useStore.count)
</script>
效果如下:
但是我们觉得每一次都需要通过容器名来调用状态,还是比较麻烦,我们想直接通过状态名来调用。所以我们就需要解构容器中的状态数据了。这就是解构Pinai容器中数据的概念。
解构数据无法满足响应式数据
我们可以直接定义一个对象,来获得容器中的数据,如下:
<template>
<p>{{ useStore.count }}</p>
<p>{{ useStore.foo }}</p>
<hr>
<p>{{ count }}</p>
<p>{{ foo }}</p>
</template>
<script lang="ts" setup>
import { useMainStore } from "../store"
const useStore = useMainStore()
console.log(useStore.count)
//这是有问题的,因为这样拿到的数据是一次性的,不是响应式的
const { count, foo } = useStore
</script>
效果如下:
但是这是有问题的的,这样拿到的数据不是响应式的数据,只是一次性的。
使用Pinia提供的API
其实Pinia官方给我们提供了一个API,叫做storeToRefs
,可以结构容器获得响应式数据,如下:
<template>
<p>{{ useStore.count }}</p>
<p>{{ useStore.foo }}</p>
<hr>
<p>{{ count }}</p>
<p>{{ foo }}</p>
<hr>
<p>
<button v-on:click="handleChangeState">修改数据</button>
</p>
</template>
<script lang="ts" setup>
import { storeToRefs } from "pinia"
import { useMainStore } from "../store"
const useStore = useMainStore()
console.log(useStore.count)
//这是有问题的,因为这样拿到的数据是一次性的,不是响应式的
//const { count, foo } = useStore
//解决方法就是使用
const { count, foo } = storeToRefs(useStore)
const handleChangeState = () => {
useStore.count++
}
console.log(count.value)
</script>
效果如下:
我们点击按钮,数据会相应是的发生改变!!
原理
如果我们直接使用const { count, foo } = useStore
这种方法的话,Pinia其实是把state
中的数据都做了reactive处理,其实是没用的。
但是我们使用const { count, foo } = storeToRefs(useStore)
的话,会把解构出来的数据做 ref 响应式代理。