Vue.js 3和Pinia Getters的问题



我正在从Angular切换到Vue.js,并试图理解体系结构。我目前遇到了一个根本性的问题,并且有很多变通办法,我真的只考虑临时解决方案。

这里的主要问题是Vue.js 3和Pinia之间的合作。Pinia由Store、Getters和Actions组成。有时我们在Store中有嵌套的对象,而我们只需要它的某些部分。为此,创建一个getter是完美的,例如,只输出我需要的对象的部分。

但是,如果我想从模板中更改对象的这些部分,该怎么办?我希望存储中的数据也能更改。但是由于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模板中使用的gettergetElementsForCurrentRole中,我只需要某些元素。

为了让你更容易理解,我还在这里发送模板代码:

<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函数使数据反应后,我循环使用getElementsForCurrentRolegetter。我的问题是,数据可能只是部分反应性的。例如,如果我更改Switch元素的值,则存储更新成功。这是有效的。然而,我似乎无法访问我正在循环的数组的顺序。只要我通过拖放更改顺序,就会收到消息:Write operation failed: computed value is readonly

我不明白,也无法理解。

作为一种变通方法,我目前根据事件计算拖动后数组中记录的新旧索引,并手动更新存储。但这不可能是它背后的目的。我是否从根本上误解了架构中的某些东西?如何处理这样的案件?

您使用的是getter。Getter是只读的propreties。要更新任何小齿轮库中的价值,您必须创建一个操作。您使用的是一个v模型,它在值发生变化时进行绑定和写入。因此,它可以使用getter进行读取,但不能进行写入。在你的情况下,有几种可能性。其中之一是生成一个计算属性和一个操作。像这个

actions: {
updateRole(newRole) {
this.currentRole = newRole
}

以及组件中的计算属性:

const myComputed = computed({
get: () => getElementsForCurrentRole.value,
set: (val) => updateRole(val),
})

最新更新