Предположим, у меня в приложении vue.js есть следующий шаблон:
Form.vue:
<template>
<form>
<page-1 v-if="step === 1" :firstName="firstName" :lastName="lastName" @submit="step = 2"></page-1>
<page-2 v-if="step === 2" :email="email" @submit="step = 3"></page-2>
<page-3 v-if="step === 3" :comments="comments" @submit="submit()"></page-3>
</form>
</template>
<script>
import Page1 from './Page1.vue';
import Page2 from './Page2.vue';
import Page3 from './Page3.vue';
export default {
components: {
Page1,
Page2,
Page3
},
data() {
return {
firstName: '',
lastName: '',
email: '',
comments: '',
step: 1
}
},
methods: {
submit() {
// submit the form
}
}
}
</script>
<style>
</style>
Page1.vue:
<template>
<label>First Name:</label>
<input type="text" v-model="firstName"></input>
<label>Last Name:</label>
<input type="text" v-model="lastName"></input>
<button @click="$emit('submit')">Next</button>
</template>
<script>
export default {
props: {
firstName: '',
lastName: ''
}
}
</script>
<style>
</style>
Page2.vue:
<template>
<label>Email:</label>
<input type="email" v-model="email"></input>
<button @click="$emit('submit')">Next</button>
</template>
<script>
export default {
props: {
email: ''
}
}
</script>
<style>
</style>
Page3.vue:
<template>
<label>Comments:</label>
<textarea v-model="comments"></textarea>
<button @click="$emit('submit')">Submit</button>
</template>
<script>
export default {
props: {
comments: ''
}
}
</script>
<style>
</style>
По сути, это форма из трех страниц. Родительский компонент - это форма, а каждая страница - дочерний компонент. Родительский компонент отслеживает поля формы со своими данными и передает их на каждую страницу с помощью свойств. Но это плохой дизайн, потому что я изменяю свойства в каждом дочернем компоненте, назначая их v-модели на каждом входе.
Большинство решений этой проблемы, которые я видел в Google, предлагают использовать вычисляемые свойства, но поскольку я использую v-модель, мне нужно поддерживать двустороннюю привязку, а вычисляемые свойства кажутся только односторонними. Поэтому мне интересно, является ли следующий шаблон для решения этой проблемы, который считается хорошим дизайном:
Form.vue:
<template>
<form>
<page-1 v-if="step === 1" :firstName="firstName" :lastName="lastName" @first-name-changed="val => firstName=val" last-name-changed="val => lastName=val" @submit="step = 2"></page-1>
<page-2 v-if="step === 2" :email="email" @email-changed="val => email=val" @submit="step = 3"></page-2>
<page-3 v-if="step === 3" :comments="comments" @comments-changed="val => comments=val" @submit="submit()"></page-3>
</form>
</template>
<script>
import Page1 from './Page1.vue';
import Page2 from './Page2.vue';
import Page3 from './Page3.vue';
export default {
components: {
Page1,
Page2,
Page3
},
data() {
return {
firstName: '',
lastName: '',
email: '',
comments: '',
step: 1
}
},
methods: {
submit() {
// submit the form
}
}
}
</script>
<style>
</style>
Page1.vue:
<template>
<label>First Name:</label>
<input type="text" v-model="firstNameData"></input>
<label>Last Name:</label>
<input type="text" v-model="lastNameData"></input>
<button @click="$emit('submit')">Next</button>
</template>
<script>
export default {
props: {
firstName: '',
lastName: ''
},
data() {
return {
firstNameData: '',
lastNameData: ''
}
},
watch: {
'firstNameData': function() {
this.$emit('first-name-changed', this.firstNameData);
},
'lastNameData': function() {
this.$emit('last-name-changed', this.lastNameData);
}
},
created() {
this.firstNameData = this.firstName;
this.lastNameData = this.lastName;
}
}
</script>
<style>
</style>
Идея состоит в том, чтобы не повторять тот же шаблон в двух других дочерних компонентах, чтобы скопировать значения реквизитов в переменные данных в дочерних компонентах, привязать переменные данных к входам, следить за изменениями в переменных данных и генерировать резервные копии событий. родителю, когда они меняются. Эти выбросы будут приходить с новыми значениями, и родитель будет назначать эти новые значения своим переменным данных.
Мне не нужно беспокоиться о динамическом изменении свойств, передаваемых каждому дочернему компоненту. Единственная причина, по которой я хочу передать их дочерним компонентам, заключается в том, что пользователь может захотеть повторно загрузить форму из черновика (в противном случае не было бы необходимости в реквизитах вообще).
У меня вопрос: хороший ли это шаблон дизайна?