无法在较高级别的表单之间传递表单字段

时间:2018-09-04 12:09:26

标签: javascript vue.js

我开始使用Vue,我需要创建一种形式的分层选择字段。这是A的选定选项,使用该选项调用API以获取B的选项,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>

然后我有一个SelectZip.vueSelectState.vue相同,除了它有一个axios.get('XXX', params = {'state': ???})的参数。但是我一直在坚持如何“传递”该必要参数。

谢谢!

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

<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>

1 个答案:

答案 0 :(得分:1)

您可以通过在主表单组件的选定组件中添加'state'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属性来访问它们。