Vue.js 3 和 Pinia Getters 的问题
P粉668019339
P粉668019339 2023-11-03 18:52:56
0
1
693

我正在从 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 元素的值,则商店更新成功。这有效。但是,我似乎无法访问正在循环的数组的顺序。一旦我通过拖放更改顺序,我就会收到消息:写入操作失败:计算值是只读

我不明白这个,我无法理解。

作为一种解决方法,我目前根据事件计算拖动后数组中记录的旧索引和新索引,并手动更新存储。但这不可能是其背后的目的。我是否从根本上误解了架构中的某些内容?对于这样的情况,人们会如何处理?

P粉668019339
P粉668019339

全部回复(1)
P粉034571623

您正在使用吸气剂。 Getter 是只读属性。要更新任何 pinia 商店中的值,您必须创建一个操作。 并且您正在使用 v-model,它会在值更改时进行绑定和写入。因此,它可以使用 getter 读取,但不能写入。对于你的情况有几种可能性。其中之一是创建计算属性和操作。像这样

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

以及组件中的计算属性:

const myComputed = computed({
  get: () => getElementsForCurrentRole.value,
  set: (val) => updateRole(val),
})
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板