Vue.js 3 和 Pinia Getters 的問題
P粉668019339
P粉668019339 2023-11-03 18:52:56
0
1
700

我正在從 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),
})
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板