【问题标题】:Making Dynamically Set Object Values Reactive in VueJS data() & v-bind: sync Forms在 VueJS data() 和 v-bind: 同步表单中动态设置对象值
【发布时间】:2020-04-13 15:50:31
【问题描述】:

所以,我正在构建一个动态表单生成器,该生成器基于在data() 中创建的对象生成表单为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>

Click here to view this project on GitHub

【问题讨论】:

标签: javascript vue.js javascript-objects vue-reactivity


【解决方案1】:

此答案由 Michael Levy 在 cmets 中英勇发布的 Vue reactivity doc link 提供。

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

新的beforeMount() 使用Vue.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)
    }
  },

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 2018-12-11
    • 2018-05-15
    相关资源
    最近更新 更多