Vuejs 获取多种输入形式的索引

Vuejs get index in multiple input forms

我有一个字符串数组,例如:

questions: [
  "Question 1?",
  "Question 2?",
  "Question 3?",
  "Question 4?",
],

然后我的 data() 中有表单字段,例如:

legitForm: {
  name: '', // this will be equal to question string
  answer: '',
  description: '',
  duration: '',
},

Now, the problem I'm facing is when I fill inputs for any of questions above the same field for other questions gets same value.

这是我的模板代码:

<div v-for="(question, index) in questions" :key="index">
    <form @submit.prevent="legitStore(question)" method="post">
        <div class="row">
            <div class="col-md-12">
                <p>
                    <strong>{{question}}</strong>
                </p>
            </div>
            <div class="col-md-6">
                <label for="answer">Answer</label>
                <select class="mb-1 field" v-model="legitForm.answer" name="answer" id="answer">
                    <option value="1">Yes</option>
                    <option value="0">No</option>
                </select>
            </div>
            <div class="col-md-6">
                <label for="duration">Duration</label>
                <input class="field" v-model="legitForm.duration" type="text">
            </div>
            <div class="col-md-12">
                <label for="description">Description</label>
                <textarea style="height: 190px;" type="text" cols="5" rows="10" id="address" class="mb-1 field" v-model="legitForm.description"></textarea>
            </div>
        </div>
        <button type="submit" class="saveButtonExperience float-right btn btn--custom">
            <span class="text">Save</span>
        </button>
    </form>
</div>

这是我的 post 向后端发送数据的方法:

legitStore(question) {
    this.legitForm.name = question; // set "name" in `legitForm` to value of `question` string
    axios.post('/api/auth/userLegitsStore', this.legitForm, {
        headers: {
            Authorization: localStorage.getItem('access_token')
        }
    })
    .then(res => {
        // reset my data after success
        this.legitForm = {
            name: '',
            answer: '',
            description: '',
            duration: '',
        };
    })
    .catch(error => {
        var errors = error.response.data;
        let errorsHtml = '<ol>';
        $.each(errors.errors,function (k,v) {
            errorsHtml += '<li>'+ v + '</li>';
        });
        errorsHtml += '</ol>';
        console.log(errorsHtml);
    })
},

这是问题截图:

Note: I've tried to

  1. change legitForm to array like legitForm: [], and legitForm: [{....}]
  2. add index to my inputs v-model

but I've got errors so i wasn't sure what I'm doing wrong, that's why I'm asking here.

就像你说的,你在这里试过:

change legitForm to array like legitForm: [], and legitForm: [{....}]

add index to my inputs v-model

你应该这样做。

我会将 legitForm 更改为:

//create legitForms equal to the length of questions
const legitForms = [];

for (i in questions) legitForms.push(
  {
    name: '', // this will be equal to question string
    answer: '',
    description: '',
    duration: '',
  }
);

并在模板中:

<div v-for="(question, index) in questions" :key="index">
    <form @submit.prevent="legitStore(question)" method="post">
        <div class="row">
            <div class="col-md-12">
                <p>
                    <strong>{{question}}</strong>
                </p>
            </div>
            <div class="col-md-6">
                <label for="answer">Answer</label>
                <select class="mb-1 field" v-model="legitForms[index].answer" name="answer" id="answer">
                    <option value="1">Yes</option>
                    <option value="0">No</option>
                </select>
            </div>
            <div class="col-md-6">
                <label for="duration">Duration</label>
                <input class="field" v-model="legitForms[index].duration" type="text">
            </div>
            <div class="col-md-12">
                <label for="description">Description</label>
                <textarea style="height: 190px;" type="text" cols="5" rows="10" id="address" class="mb-1 field" v-model="legitForms[index].description"></textarea>
            </div>
        </div>
        <button type="submit" class="saveButtonExperience float-right btn btn--custom">
            <span class="text">Save</span>
        </button>
    </form>
</div>

如果您将问题视为问题和答案,您可以这样做:

questions: [
  {
    question: 'Question 1',
    answer: null,
    description: null,
    duration: null,
  },
  {
    question: 'Question 2',
    answer: null,
    description: null,
    duration: null,
  },
]

然后当循环遍历你的表单时,它会更像这样:

<div v-for="(question, index) in questions" :key="index">
    <form @submit.prevent="legitStore(question)" method="post">
      ...
      <select class="mb-1 field" v-model="question.answer" name="answer" id="answer">
        <option value="1">Yes</option>
        <option value="0">No</option>
      </select>
      ...
    </form>
</div>

并且在存储功能中,您可以发送问题中的数据而不是 this.legitForm

<div v-for="(question, index) in questions" :key="index">

在您的模板中,您遍历 questions 并在此标记渲染对象中 legitForm 所有问题都将引用同一个对象,这就是为什么所有问题都具有相同数据的原因。

您应该已经创建了一个问题数组,其中包含自己的问题内容,​​例如

<template>
  <div v-for="(question, index) in questions" :key="index">
    <form @submit.prevent="legitStore(question)" method="post">
      ...
      <div class="col-md-12">
         <p>
            <strong>{{question.id}}</strong>
         </p>
      </div>
      ...
      <select class="mb-1 field" v-model="question.answer" name="answer" id="answer">
        <option value="1">Yes</option>
        <option value="0">No</option>
      </select>
      ...
    </form>
  </div>
</template>

<script>
class QuestionForm {
  // pass default value if you want
  name = ''
  answer = ''
  description = ''
  duration = ''
  id = ''
  constructor(form) {
    Object.assign(this, form)
  }
}

function initQuestions(num) {
  // can generate a Set object cause question are unique
  return Array.from({ length: num }, (v, i) => i).map(_j => new QuestionForm())
}

export default {
  data() {
    return {
      questions: initQuestions(5), // pass number of question you want to generate
    }
  }
}
</script>