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

news/2024/11/15 1:54:25/

官网解读

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对象的值也会随之更新,保证了在组件中使用时的响应性。


http://www.ppmy.cn/news/1381976.html

相关文章

力扣-[700. 二叉搜索树中的搜索]

递归法 确定递归函数的参数和返回值 递归函数的参数传入的就是根节点和要搜索的数值&#xff0c;返回的就是以这个搜索数值所在的节点。 代码如下&#xff1a; public TreeNode searchBST(TreeNode root, int val) 确定终止条件 如果root为空&#xff0c;返回null&#xff0c…

xss.pwnfunction.com靶机 Warmups

通关要求弹出警告框alert(1337) 没有用户交互 不能使用外链接 在chrome中测试 Ma Spaghet! 通过分析代码我们可以看到它直接用innerHTML将接收的内容赋值 但是我们不能使用<script>标签因为&#xff1a;HTML 5 中指定不执行由 innerHTML 插入的 <script> 标签。 所…

flume系列之:为flume agent组增加新的节点,提高flume agent组消费能力

flume系列之:为flume agent组增加新的节点,提高flume agent组消费能力 一、拷贝服务的systemctl文件二、拷贝jmx导出程序三、拷贝jmx导出数据格式配置文件四、拷贝flume agent配置五、启动flume agent和jmx服务一、拷贝服务的systemctl文件 flume agent服务flume agent jmx服…

wayland(xdg_wm_base) + egl + opengles 渲染使用纹理贴图的旋转 3D 立方体实例(十三)

文章目录 前言一、使用 stb_image 库加载纹理图片1. 获取 stb_image.h 头文件2. 使用 stb_image.h 中的相关接口加载纹理图片3. 纹理图片——cordeBouee4.jpg二、渲染使用纹理贴图的旋转 3D 立方体1. egl_wayland_texture_cube.c2. Matrix.h 和 Matrix.c3. xdg-shell-client-pr…

Linux本地搭建FastDFS系统

文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…

手机App防沉迷系统C卷(JavaPythonC++Node.jsC语言)

智能手机方便了我们生活的同时,也侵占了我们不少的时间。"手机App防沉迷系统"能够让我们每天合理的规划手机App使用时间,在正确的时间做正确的事。 它的大概原理是这样的: 1、在一天24小时内,可注册每个App的允许使用时段; 2、一个时段只能使用一个App,举例说明…

VUE+内置iframe传值失效问题解决

起因&#xff1a; 公司业务需要计算建筑物截收面积&#xff0c;然后我采用的是openCV来计算&#xff0c;在vue内部引用不了&#xff0c;然后就采用了iframe原生html来完成&#xff1b;功能实现了我想让iframe和vue通信&#xff1b;然后用原有方式试了多次都失败了&#xff0c;i…

golang sync.Pool 指针数据覆盖问题

场景 1. sync.Pool设置 var stringPool sync.Pool{New: func() any {return new([]string)}, }func NewString() *[]string {v : stringPool.Get().(*[]string)return v }func PutString(s *[]string) {if s nil {return}if cap(*s) > 2048 {s nil} else {*s (*s)[:0]…