javascript - Hva er den vanlige måten å kapsle inn data i Pinia-butikker når man bruker komposisjons-APIet?
Jeg bruker Vue 3 med Pinia og ønsker å bruke composition API inne i mine Pinia-butikker. Gitt følgende eksempel på en butikk
export const useMyStore = defineStore("my", () => {
const currentState = ref(0);
return { currentState };
}
);
Jeg kan direkte endre verdien av currentState. Jeg er ikke sikker på om dette er riktig måte å gjøre det på, eller om jeg bør forhindre dette og tilby noen get- og set-funksjoner som
export const useMyStore = defineStore("my", () => {
const currentState = ref(false);
const readonlyCurrentState = computed((): Readonly<boolean> => currentState.value);
function changeState(newState: boolean) {
currentState.value = newState;
}
return { readonlyCurrentState, changeState };
}
);
Options-API-en løser problemet mitt ved å tilby getters og actions, så jeg tenkte om jeg burde oppnå det samme her.
Dette kan være et spørsmål basert på mening, men jeg ønsker å vite om jeg bør kapsle inn tilstanden currentState for å forhindre utilsiktet korrupsjon.
Svar #1
Jeg kan direkte endre verdien av
currentState
Ja, dette er bevisst. Som beskrevet i sammenligning med Vuex
Mutasjoner eksisterer ikke lenger. De ble veldig ofte sett på som ekstremt ordkrevende. De brakte opprinnelig integrering med devtools, men det er ikke lenger et problem.
Dette er en mer teknisk grunn, men du kan lese mer fra selve forfatteren (og folk som ikke liker denne nye "friheten") i denne diskusjonen: Legg til et alternativ for å ikke tillate direkte tilstandsmodifikasjon fra komponenten
Generelt viser koden i spørsmålet ditt poenget perfekt - mye unødvendig kode bare for å endre en enkel boolsk verdi. Selvfølgelig finnes det tilfeller der data er mer kompleks, du vil håndheve noen begrensninger osv., hvor ubegrenset direkte endring kan anses som farlig. Jeg tror mønsteret i spørsmålet ditt er helt brukbart, og du kan finne flere ideer (og eksperimentell "strict mode"-støttecommit som venter på tilbakemelding) i den lenkede diskusjonen.
Personlig synes jeg at mange av sikkerhetssjekkene kan gjøres med linting og spesielt TypeScript-definisjoner. Du får den ekstra sikkerheten under utvikling uten å betale prisen ved kjøretid (når det gjelder ekstra kode som kjører og blir pakket og servert). Det flotte med Pinia er at det gir oss valget om hvordan vi skal nærme oss problemet...
Svar #2
I et tilfelle der du virkelig ønsker å begrense tilgang til data, anbefales dessverre ikke din andre tilnærming. Pinia-dokumentasjonen sier:
Du må returnere alle tilstands-egenskaper i setup-butikker for at Pinia skal plukke dem opp som tilstand. Med andre ord, du kan ikke ha private tilstands-egenskaper i butikker.
For å omgå det, foreslår Mastering Pinia-bloggen å opprette en andre, "privat" butikk som refereres til (men ikke eksponeres) av den første. For å utvide eksemplet ditt:
// This new store is not exported
const useMyPrivateStore = defineStore('my-private', () => {
const currentState = ref(false);
return { currentState }
})
export const useMyStore = defineStore("my", () => {
// You can use stores within stores
const privateState = useMyPrivateStore()
const readonlyCurrentState = computed(() => privateState.currentState);
const changeState = (newState: boolean) => privateState.currentState = newState;
return { readonlyCurrentState, changeState };
}
);
