Раньше я использовал VueJS и Vuex. Не в производстве, просто для некоторых простых личных побочных проектов, и это было довольно прямолинейно.
Однако теперь я столкнулся с проблемой, которая немного сложнее, но использование Vuex уже кажется намного более сложным. Поэтому я ищу некоторые рекомендации здесь.
В главном представлении я представляю пользователю список карточек. Карта представляет собой редактируемую форму примерно десяти свойств (вводы, выбор и т. д.). Я, очевидно, реализовал компонент для этих карт, так как они повторяются в виде списка. Мой первый наивный подход заключался в том, чтобы получить список — назовем это формами — из моего магазина, а затем с помощью v-for
представить карточку для каждой формы в этом списке форм. Форма передается дочернему компоненту как свойство.
Теперь я хочу привязать элементы управления формы к свойствам. Для этого я реализовал Двусторонние вычисляемые свойства, чтобы правильно использовать мутации моего хранилища. Но реализация пользовательского вычисляемого свойства с геттером и сеттером плюс мутация для каждого свойства в моей модели кажется чрезвычайно повторяющейся. Кроме того, в моем состоянии формы представляют собой массив. Поэтому я должен передать идентификатор формы для редактирования в магазине каждой мутации.
Что-то еще, что я имел в виду, это просто передать идентификатор хранилища формы дочернему компоненту и иметь геттеры «по идентификатору» для каждого свойства моей модели, а также соответствующую мутацию. Но это тоже не похоже на правильный способ сделать это. По сути то же самое, верно?!
Есть ли лучшее решение этой проблемы? Может быть, я просто что-то упускаю или усложняю.
Урезанный пример:
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>
Можете ли вы привести самый простой пример того, что вы описываете?
В режиме реального времени. Вот почему я пытаюсь использовать v-модель с вычисляемыми свойствами. Но отображение этого с помощью Vuex кажется излишним.
Используйте индекс и устанавливайте весь объект формы в одном вычисляемом установщике всякий раз, когда изменяется какое-либо поле.
Было бы неплохо создать вычисляемый установщик для всего объекта формы с помощью клона, но это не сработает, поскольку изменения не вызовут срабатывания вычисляемого установщика.
If anyone wants to explore this interesting failure, see here)
Чтобы обойти это, вы можете использовать часы и клон данных:
<v-form>
<v-text-field v-model = "clone.title" />
<v-text-field v-model = "clone.text" />
</v-form>
props: ['index', 'card'],
data() {
return {
clone: {}
}
},
watch: {
card: {
handler(card) {
this.clone = { ...card }
},
immediate: true,
deep: true
},
clone: {
handler(n,o) {
if (n === o) {
this.$store.commit('SET_CARD', { index: this.index, card: n })
}
},
deep: true
}
}
Ваш v-for
:
<EditableCard v-for = "(card, index) in cards" :card = "card" :index = "index" :key = "index" />
Мутация:
mutations: {
SET_CARD(state, { index, card }) {
Vue.set(state.cards, index, card);
}
}
Это намного сложнее, чем должно быть... но это работает.
Вы хотите, чтобы ваши формы редактировались в режиме реального времени или, скорее, изменялись сразу после нажатия кнопки «Сохранить»?