假设我的 vue.js 应用程序中有以下模式:
表单.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>
页面1.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>
页面2.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>
页面3.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>
本质上,它是一个三页的表格。父组件是表单,每个页面都是一个子组件。父组件使用其数据跟踪表单字段,并通过 props 将它们传递到每个页面。但这是一个糟糕的设计,因为我通过在每个输入上将它们分配给 v-model 来改变每个子组件中的道具。
我在 Google 上看到的这个问题的大多数解决方案都建议使用计算属性,但是因为我使用的是 v-model,所以我需要维护双向绑定,而计算属性似乎只是单向的。所以我想知道以下是否是解决这个问题的常见模式,这被认为是一个好的设计:
表单.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>
页面1.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>
在其他两个子组件中不重复相同的模式,想法是将 props 的值复制到子组件中的数据变量,将数据变量绑定到输入,观察数据变量的变化并发出事件备份当他们改变时给父母。这些发射将带有新值,并且父级会将这些新值分配给其数据变量。
我不需要担心传递给每个子组件的道具会动态变化。我想将它们传递给子组件的唯一原因是用户可能想从草稿中重新加载表单(否则,根本不需要道具)。
我的问题是:这是一个好的设计模式吗?