V模型可动态创建数组中的对象

时间:2019-08-21 15:29:54

标签: javascript vue.js vuejs2

我有一个数组,我想在数组中动态创建对象并向其v-model输入,这就是我的代码:

这是数组

new_questions:{
    questionrecord: []
}

这是输入

<div class="form-fields" v-for="(field, index) in question_fields">
    <div class="form-group">
        <select class="form-control" v-model="new_questions.questionrecord[index].questionresponse">
            <option value="single_answer">Single Answer (For regular question)</option>
            <option value="multiple_answer">Multiple Answer (For situational judgement question)</option>
        </select>
    </div>
</div>

我希望数组看起来像

new_questions:{
    questionrecord: [
        {
            questiontype: "single_answer"
        },
        {
            questiontype: "multiple_answer"
        },
        ...
    ]
}

但是我得到一个错误:

[Vue warn]: Error in render: "TypeError: Cannot read property 'questionresponse' of undefined

我该如何实现?

2 个答案:

答案 0 :(得分:1)

V模型仅是@input="..":value=".."的语法糖

要按照您描述的方式操作数据,可能有必要区分两者并编写一个setterMethod来处理动态(可能不存在)属性。

根据数据的结构,是否要处理不同嵌套级别上的属性等,您的setterMethod可能会变得有些复杂。像lodash.setWith这样的助手可以帮助您一点。

一个非常具体的例子:

<template>
...
  <div class="form-fields" v-for="(field, index) in question_fields">
    <div class="form-group">
      <select class="form-control"
       :value="new_questions.questionrecord[index].questionresponse"
       @input="setValue($event.target.value, index)"
      >
        <option value="single_answer">Single Answer (For regular question)</option>
        <option value="multiple_answer">Multiple Answer (For situational judgement question)</option>
      </select>
    </div>
  </div>
...
</template>

<script>
export default {
  data() {
    return {
      new_questions: {
        questionrecord: [],
      }
    };
  },

  created() {
    // prepopulate your questionrecord array so you don't throw TypeErrors
    const dummyArray = Array(this.question_fields.length);
    this.new_questions.questionrecord.push(...dummyArray);
  },

  methods() {
    setValue(value, index) {
      const newRecord = {
        questionresponse: value,
      };
      // in order to create responsive array entries in vue, you have to use native array methods - don't set the value by index
      // (e.g. this.new_questions.questionrecorcd[index] = newRecord);
      this.new_questions.questionrecord.splice(index, 1, newRecord);
      // Object properties would need to be created with Vue.set(rootObj, key, value);
    }
  }
};
</script>

答案 1 :(得分:0)

不知道您的question_fields看起来如何,但是我测试了一些伪值,并且此代码对我有用。

new Vue({
  el: "#app",
  data() {
    return {
      question_fields: ['test', 'test1'],
    	new_questions:{
          questionrecord: [
              {
                  questiontype: "single_answer"
              },
              {
                  questiontype: "multiple_answer"
              }
          ]
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div class="form-fields" v-for="(field, index) in question_fields">
    <div class="form-group">
      <select class="form-control" v-model="new_questions.questionrecord[index].questionresponse">
        <option value="single_answer">Single Answer (For regular question)</option>
        <option value="multiple_answer">Multiple Answer (For situational judgement question)</option>
      </select>
    </div>
  </div>
  
   <pre>{{new_questions.questionrecord}}</pre>
</div>