0

因此,我正在构建一个动态表单生成器,它基于在data()as中创建的对象生成表单form: {},然后设置问题键/值对,beforeMount()其中绑定到使用v-bind.sync.

我希望能够在form: {}页面上看到键/值对的更改,但由于键值对是动态生成的,因此它们不是反应性的。

当我登录时this.form,我可以看到对象值的更改,但我认为我缺少一个让它们在页面本身上刷新的功能:

带有控制台日志的页面截图

父组件,其中设置了空的表单对象:

<template lang="html">
  <div>
    <DynamicForm
      v-bind.sync="form"
      :questions="questions"
      :onSubmit="onSubmit"
    >
      <template slot="buttons">
        <b-button
          type="submit"
          block
        >
          Submit
        </b-button>
      </template>
    </DynamicForm>

    <div class="form-output">
      {{form}}
    </div>
  </div>
</template>

<script>
export default {
  // ...
  data(){
    return {
      form: {},
// questions normally loaded via http request, set here in data for example's sake
      questions: [
        {
          "type": "TEXT",
          "label": "Name",
          "model": "name"
        },
        {
          "type": "NUMBER",
          "label": "Age",
          "model": "age"
        }
      ]
    }
  },
  beforeMount(){
    let questionArray = this.questions

    for(var i = 0; i < questionArray.length; i++){
      this.form[questionArray[i].model] = questionArray[i].defaultValue ? questionArray[i].defaultValue : ''
    }
  },
  // ...
}

DynamicForm组件发出如下:

<template lang="html">
    <template v-for="question in questions">
        <b-form-input
          :v-model="question.model"
          @input="formInput(question.model, $event)"
        >
        </b-form-input>
    </template>
  </b-form>
<script>
export default {
  // ...
  props: {
    questions: Array,
    onSubmit: Function
  },
  methods: {
    formInput(key, value) {
      console.log(`Key: ${key}, Value: ${value}`)
      this.$emit(`update:${key}`, value)
    },
  },
  // ...
}
</script>

单击此处在 GitHub 上查看此项目

4

1 回答 1

2

这个答案是由 Michael Levy 在评论中英勇地发布的Vue 反应性文档链接提供的。

为了使动态生成的表单内容具有响应性,我们必须使用Vue.set在组件中的别名设置表单键值对this.$set(object, key, value)

新的beforeMount()usingVue.set而不是this.form[questionArray[i].model] = questionArray[i].value

  beforeMount(){
    let questionArray = this.questions

    for(var i = 0; i < questionArray.length; i++){
      var valueToSet = questionArray[i].defaultValue ? questionArray[i].defaultValue : ''

      this.$set(this.form, questionArray[i].model, valueToSet)
    }
  },
于 2019-12-21T15:03:18.877 回答