我正在从 Angular 切换到 Vue.js 并尝试理解其架构。我目前遇到了一个基本问题,并使用了很多解决方法,但我实际上只考虑临时解决方案。
这里的主要问题是 Vue.js 3 和 Pinia 之间的协作。 Pinia 由 Store、Getter 和 Action 组成。有时我们在 Store 中有非常嵌套的对象,我们只需要它的某些部分。为此,创建一个 getter 是完美的,例如,仅输出我需要的对象部分。
但是如果我想从模板中精确更改对象的那些部分怎么办?我的愿望是商店中的数据也发生变化。但由于吸气剂是只读的,这是不可能的。
这里如何进行?
当然,我想向您展示一个示例,通过一些实践来强调我的解释。
export const useGeneralStore = defineStore('general', { state: () => { return { roles: [], currentRole: 'basic', } }, getters: { getElementsForCurrentRole: (state) => { let role = state.roles.find((role) => { return role.value == state.currentRole; }); if (role) { return role.data; } } }, actions: {} })
我在这里使用一个非常嵌套的对象 roles
创建一个商店。在我在 v-for 模板中使用的 getter getElementsForCurrentRole
中,我只需要某些元素。
为了方便大家理解,我也将模板代码发在这里:
<template> <div class="element-container"> <div v-for="cat of elementCategories" :key="cat"> <h4>{{cat}}</h4> <draggable v-model="getElementsForCurrentRole" :group="cat" @end="save" item-key="name"> <template #item="{element}"> <n-card v-if="element.category == cat" class="element" :class="element.name" :title="element.name" size="small" header-style="{titleFontSizeSmall: 8px}" hoverable> <n-switch v-model:value="element.active" @update:value="save(element)" size="small" /> </n-card> </template> </draggable> </div> </div> </template> <script setup> import { NCard, NSwitch, useMessage } from 'naive-ui'; import draggable from 'vuedraggable' import { usePermissionsStore } from '@/stores/permissions'; import { storeToRefs } from 'pinia'; const permissionsStore = usePermissionsStore(); const { getElementsForCurrentRole } = storeToRefs(permissionsStore); const elementCategories = ['basic', 'professional']; </script>
使用文档中提到的 storeToRefs
函数后,我循环遍历 getElementsForCurrentRole
getter,以使数据具有反应性。我的问题是数据可能只是部分反应性的。例如,如果我更改 Switch
元素的值,则商店更新成功。这有效。但是,我似乎无法访问正在循环的数组的顺序。一旦我通过拖放更改顺序,我就会收到消息:写入操作失败:计算值是只读
。
我不明白这个,我无法理解。
作为一种解决方法,我目前根据事件计算拖动后数组中记录的旧索引和新索引,并手动更新存储。但这不可能是其背后的目的。我是否从根本上误解了架构中的某些内容?对于这样的情况,人们会如何处理?
您正在使用吸气剂。 Getter 是只读属性。要更新任何 pinia 商店中的值,您必须创建一个操作。 并且您正在使用 v-model,它会在值更改时进行绑定和写入。因此,它可以使用 getter 读取,但不能写入。对于你的情况有几种可能性。其中之一是创建计算属性和操作。像这样
以及组件中的计算属性: