我正在從 Angular 切換到 Vue.js 并嘗試?yán)斫馄浼軜?gòu)。我目前遇到了一個(gè)基本問(wèn)題,并使用了很多解決方法,但我實(shí)際上只考慮臨時(shí)解決方案。
這里的主要問(wèn)題是 Vue.js 3 和 Pinia 之間的協(xié)作。 Pinia 由 Store、Getter 和 Action 組成。有時(shí)我們?cè)?Store 中有非常嵌套的對(duì)象,我們只需要它的某些部分。為此,創(chuàng)建一個(gè) getter 是完美的,例如,僅輸出我需要的對(duì)象部分。
但是如果我想從模板中精確更改對(duì)象的那些部分怎么辦?我的愿望是商店中的數(shù)據(jù)也發(fā)生變化。但由于吸氣劑是只讀的,這是不可能的。
這里如何進(jìn)行?
當(dāng)然,我想向您展示一個(gè)示例,通過(guò)一些實(shí)踐來(lái)強(qiáng)調(diào)我的解釋。
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: {} })
我在這里使用一個(gè)非常嵌套的對(duì)象 roles
創(chuàng)建一個(gè)商店。在我在 v-for 模板中使用的 getter getElementsForCurrentRole
中,我只需要某些元素。
為了方便大家理解,我也將模板代碼發(fā)在這里:
<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
函數(shù)后,我循環(huán)遍歷 getElementsForCurrentRole
getter,以使數(shù)據(jù)具有反應(yīng)性。我的問(wèn)題是數(shù)據(jù)可能只是部分反應(yīng)性的。例如,如果我更改 Switch
元素的值,則商店更新成功。這有效。但是,我似乎無(wú)法訪問(wèn)正在循環(huán)的數(shù)組的順序。一旦我通過(guò)拖放更改順序,我就會(huì)收到消息:寫(xiě)入操作失敗:計(jì)算值是只讀
。
我不明白這個(gè),我無(wú)法理解。
作為一種解決方法,我目前根據(jù)事件計(jì)算拖動(dòng)后數(shù)組中記錄的舊索引和新索引,并手動(dòng)更新存儲(chǔ)。但這不可能是其背后的目的。我是否從根本上誤解了架構(gòu)中的某些內(nèi)容?對(duì)于這樣的情況,人們會(huì)如何處理?
您正在使用吸氣劑。 Getter 是只讀屬性。要更新任何 pinia 商店中的值,您必須創(chuàng)建一個(gè)操作。 并且您正在使用 v-model,它會(huì)在值更改時(shí)進(jìn)行綁定和寫(xiě)入。因此,它可以使用 getter 讀取,但不能寫(xiě)入。對(duì)于你的情況有幾種可能性。其中之一是創(chuàng)建計(jì)算屬性和操作。像這樣
actions: { updateRole(newRole) { this.currentRole = newRole }
以及組件中的計(jì)算屬性:
const myComputed = computed({ get: () => getElementsForCurrentRole.value, set: (val) => updateRole(val), })