我正在從 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粉0345716232023-11-04 15:30:00
您正在使用吸氣劑。 Getter 是唯讀屬性。要更新任何 pinia 商店中的值,您必須建立一個操作。 並且您正在使用 v-model,它會在值更改時進行綁定和寫入。因此,它可以使用 getter 讀取,但不能寫入。對於你的情況有幾種可能性。其中之一是創建計算屬性和操作。像這樣
actions: { updateRole(newRole) { this.currentRole = newRole }
以及元件中的計算屬性:
const myComputed = computed({ get: () => getElementsForCurrentRole.value, set: (val) => updateRole(val), })