在更高级别表单的组件之间传递表单字段时遇到问题



我开始使用 Vue,我需要创建一种分层选择字段的形式。 这是 A 的选定选项,使用它来调用 API 以获取 B 的选项,这决定了 C 的选项。

我对前端框架仍然很陌生,所以这可能是一个糟糕的设计。 然而,并不是每个在视图中包含A(SelectState.vue(都需要所有的孩子,所以使它们模块化是我的第一个想法。

目前我有一个显示选择选项的顶级组件:

SelectState.vue

<template>
<div id="select-state">
<span>{{ label }}</span>
<select v-model="selectedState">
<option v-for="state in states" :key="state">
{{ state }}
</option>
</select>
</div>
</template>
<script>
export default {
name: 'select-state',
data: function () {
return {
selectedState: '',
states: ['TX']
}
},
props: ['label']
// this.states = axios.get('xxx')
}
</script>

Index.vue

<template>
<div id="form">
<v-select-state label="State"></v-select-state>
<v-select-zip label="Zip"></v-select-zip>
</div>
</template>
<script>
import SelectState from './SelectState.vue'
import SelectZip from './SelectZip.vue'
export default {
name: 'Index',
components: {
'v-select-state': SelectState,
'v-select-Zip': SelectZip
}
}
</script>

然后我有一个与SelectState.vue相同的SelectZip.vue,只是它有一个axios.get('XXX', params = {'state': ???})参数. 但是我坚持如何"传递"该必要的参数。

提前感谢!

编辑:结合@dziraf的回答,我的工作虽然冗长SelectedZip.vue如下:

<template>
<div id="select_zip">
<span>{{ label }}</span>
<select v-model="selected_zip">
<option v-for="zip in zips" :key="zip">
{{ zip }}
</option>
</select>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'select_zip',
data: function () {
return {
zips: []
}
},
props: ['label'],
computed: {
selected_zip: {
get () { return this.$store.state.formModule.zip },
set (value) { this.$store.commit('formModule/setZips', value) }
},
selected_state: {
get () { return this.$store.state.formModule.state }
}
},
methods: {
getValidZips (state) {
axios.post('/api/v1/get_valid_zips', {
params:{'state': state }})
.then(response => {
this.zips = response.data
})
.catch(error => {
console.log(error)
})
}
},
watch: {
selected_state (value) {
this.getValidZips(value)
}
}
}
</script>

您可以通过将"状态"props添加到主表单组件中的选择组件来传递它,但我认为这不是一个好的长期解决方案。

相反,请考虑使用 Vuex。示例配置如下所示:

@/store/modules/form.js

const Form = {
namespaced: true,
state: {
state: '',
zip: ''
},
getters: {},
mutations: {
setState (state, payload) {
state.state = payload
},
setZip (state, payload) {
state.zip = payload
}
},
actions: {}
}
export default Form

@/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import Form from './modules/form'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
formModule: Form,
}
})
export default store

@/main.js

// your impots
import store from './store/index'
// your configs
new Vue({
el: '#app',
router,
store, // add store to your main Vue instance so it's accessible with this.$store
axios,
components: { App },
template: '<App/>'
});

这将是你的SelectState.vue

<template>
<div id="select-state">
<span>{{ label }}</span>
<select v-model="selectedState">
<option v-for="state in states" :key="state">
{{ state }}
</option>
</select>
</div>
</template>
<script>    
export default {
name: 'select-state',
data: function () {
return {
states: ['TX']
}
},
computed: {
selectedState: {
get() { return this.$store.state.formModule.state },
set(value) { this.$store.commit('formModule/setState', value) }
}
},
props: ['label']
}
</script>

您的SelectZip.vue将是相同的,只是您将商店的zip用作v模型。

您的商店变量可在整个应用中访问,并且您可以使用组件中的computed属性访问它们。

最新更新