2020年12月22日星期二

Proper way to use Vuex with child components

I have used VueJS and Vuex before. Not in production, just for some simple, personal side projects and it felt pretty straight forward.

However, now I face a problem that is just slightly more complex but using Vuex already feels way more complicated. So I'm looking for some guidance here.

In the main view I present a list of cards to the user. A card is an editable form of about ten properties (inputs, selects, etc.). I obviously implemented a component for these cards, since they are repeated in a list view. My first naive approach was to fetch a list of - let's call it forms - from my store and then using v-for to present a card for each form in that list of forms. The form is passed to the child component as a property.

Now I want to bind my form controls to the properties. To do this I implemented Two-way Computed Properties to properly utilize my store mutations. But it feels extremely repetitive to implement a custom computed property with getter and setter plus mutation for every property on my model. Additionally, the forms are an array in my state. So I have to pass the id of the form to edit in the store to every mutation.

Something else I had in mind was just passing the store id of the form to the child component and have "by id" getters for every property of my model as well as a matching mutation. But this doesn't feel like the proper way to do this, either. It is essentially the same, right?!

Is there a better solution to this problem? Maybe I'm just missing something or I'm overcomplicating things.

A trimmed down example:

Editor.vue:

<template>    <v-container>      <EditableCard v-for="(card, i) in cards" :key="i" :card="card" />    </v-container>  </template>    <script>  import EditableCard from "@/components/EditableCard";    import { mapGetters } from "vuex";    export default {    name: "Editor",      components: {      EditableCard    },      computed: {      ...mapGetters("cards", {        cards: "list"      })    }  };  </script>  

EditableCard:

<template>    <v-card>      <v-form>        <v-card-title>          <v-text-field v-model="title"></v-text-field>        </v-card-title>          <v-card-text>          <v-text-fieldv-model="text"></v-text-field>          <!-- And some more fields... -->        </v-card-text>      </v-form>    </v-card>  </template>    <script>  import { mapMutations } from "vuex";    export default {    name: "EditableCard",      props: {      card: Object    },      computed: {      title: {        get() {          return card.title;        },        set(value) {          this.setCardTitle(this.card.id, value);        }      },        text: {        get() {          return card.text;        },        set(value) {          this.setCardText(this.card.id, value);        }      }        // Repeat for every form input control    },      methods: {      ...mapMutations("cards", {        setCardTitle: "setTitle",        setCardText: "setText"          // Repeat for every form input control      })    }  };  </script>  
https://stackoverflow.com/questions/65417583/proper-way-to-use-vuex-with-child-components December 23, 2020 at 08:29AM

没有评论:

发表评论