首页 前端知识 vue,pinia中store赋值,推荐使用computed,能做到响应,直接解构赋值做不到,备忘

vue,pinia中store赋值,推荐使用computed,能做到响应,直接解构赋值做不到,备忘

2024-08-04 00:08:52 前端知识 前端哥 365 11 我要收藏

官网解读

https://pinia.vuejs.org/zh/core-concepts/
在这段Vue3 <script setup> 语法的代码中,有两个关于如何从 useCounterStore 返回的store对象中获取状态属性的方式进行了对比。

<script setup>
import { useCounterStore } from '@/stores/counter'
const store = useCounterStore()
// ❌ 这将不起作用,因为它破坏了响应性
// 这就和直接解构 `props` 一样
const { name, doubleCount } = store
name // 将始终是 "Eduardo"
doubleCount // 将始终是 0
setTimeout(() => {
  store.increment()
}, 1000)
// ✅ 这样写是响应式的
// 💡 当然你也可以直接使用 `store.doubleCount`
const doubleValue = computed(() => store.doubleCount)
</script>

第一种方式(不推荐):

const { name, doubleCount } = store

这种方式通过解构赋值直接从store对象中提取出 namedoubleCount 属性。然而在Vue3的响应式系统中,直接通过解构赋值提取的状态属性会失去响应性,也就是说,当 store.namestore.doubleCount 的值发生改变时,解构出来的 namedoubleCount 不会自动更新。正如注释所说,即使你在1秒后调用 store.increment() 改变了 store.count 并进而影响到 store.doubleCount 的值,解构出来的 doubleCount 仍然会保持初始值0,不会反映出最新的计算结果。

第二种方式(推荐):

const doubleValue = computed(() => store.doubleCount)

这种方式使用了Vue3的 computed 声明式依赖追踪功能,doubleValue 是一个计算属性,它依赖于 store.doubleCount。当 store.doubleCount 的值发生变化时,doubleValue 会自动更新。这就是响应式编程的优势,它能确保UI总是与数据状态保持同步。

总结:在Vue3中,当你需要从store中获取并跟踪其状态变化时,推荐使用 computed 函数创建计算属性,而不是通过解构赋值直接提取状态。

从Store 解构 ,storeToRefs

为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()。它将为每一个响应式属性创建引用。当你只使用 store 的状态而不调用任何 action 时,它会非常有用。请注意,你可以直接从 store 中解构 action,因为它们也被绑定到 store 上:

<script setup>
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// `name``doubleCount` 是响应式的 ref
// 同时通过插件添加的属性也会被提取为 ref
// 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
const { name, doubleCount } = storeToRefs(store)
// 作为 action 的 increment 可以直接解构
const { increment } = store
</script>

在Vue3的Pinia状态管理库中,storeToRefs 是一个辅助函数,用于将Pinia Store中的状态(state)和计算属性(getters)转换为可响应的对象,使得在组件中可以解构出这些属性,并保持其响应性。

当你从Pinia Store中获取整个状态对象并在组件中使用时,如果直接解构,那些嵌套的对象属性或计算属性可能会失去响应性。为了避免这个问题,可以使用 storeToRefs 将整个store对象转化为一系列可响应的ref对象。

例如:

// 定义一个Pinia Store
import { defineStore } from 'pinia';

const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
    user: {
      name: 'John Doe',
      email: 'john@example.com',
    },
  }),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
});


import { storeToRefs } from 'pinia'
// 在组件中使用store并使用storeToRefs
import { useCounterStore } from '@/stores/counter';

export default {
  setup() {
    const counterStore = useCounterStore();
    const { count, user, doubleCount } = storeToRefs(counterStore);

    // 现在count、user和doubleCount都是响应式的
    // 可以在模板中直接绑定或在逻辑中使用
    return {
      count,
      user,
      doubleCount,
    };
  },
};

在这个例子中,storeToRefs(counterStore) 返回一个对象,其中的 countuserdoubleCount 都是响应式Ref对象,当Store中的原始状态发生变化时,这些Ref对象的值也会随之更新,保证了在组件中使用时的响应性。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/14702.html
标签
评论
发布的文章

RapidJSON介绍

2024-08-14 00:08:38

jQuery 4 beta 震撼发布

2024-08-14 00:08:36

cJSON的使用

2024-08-14 00:08:36

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!