4

Maybe I'm going about this the wrong way ... but I'm trying to use a v-for loop to duplicate/remove a custom component x times. x is decided by a <select> field above. What I have works on the initial page load, but then when you select a different option, only one custom component is displayed (although x is updated). Does anyone have any idea what I am doing wrong?

// here is the select field that defines the number of enrolling students
<select name="number_students_enrolling" v-model="formFields.numberStudentsEnrolling">
    <option value="" default selected></option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
</select>

// here is the custom component I'm trying to duplicate/remove dynamically
<div class="students-container">
    <student v-for="n in formFields.numberStudentsEnrolling" :key="n" v-bind:index="n" >
    </student>
</div>

// here is the custom component
Vue.component('student', {
  props: ["index"],
  template: `
    <div class="input--student">
      <div class="input--half">
        <label>
          <span class="d-block">
            Student {{ index }} Name <span class="field--required">*</span>
          </span>
          <input type="text">
        </label>
      </div>
      <div class="input-wrap input--half">
        <label>
          <span class="d-block">
            Student {{ index }} DOB <span class="field--required">*</span>
          </span>
          <input type="text">
        </label>
      </div>
    </div>
  `
})

// Here is the Vue.js instance
var test = new Vue({
  el: '#test',
  data: { 
    formFields: {
      numberStudentsEnrolling: 3
    }
  }
});

enter image description here enter image description here

1 Answer 1

6

v-for needs a Number, but you're giving it a string (the selected value). Convert it to a Number so v-for will treat it as a range from 1 to N:

<div class="students-container">
    <student
        v-for="n in Number(formFields.numberStudentsEnrolling)"
        :key="n"
        v-bind:index="n">
    </student>
</div>

For completeness, another approach (per @HusamIbrahim) is to annotate the v-model reference with .number, which will automatically do the conversion.

<select
    name="number_students_enrolling"
    v-model.number="formFields.numberStudentsEnrolling"
>

Here's a codesandbox: https://codesandbox.io/s/xzy6or9qo

Sign up to request clarification or add additional context in comments.

6 Comments

But v-for does work with numbers. In fact there's a unit test for this feature in the codebase. Search range v-for.
@Husam Ibrahim that's why I was confused, because I couldn't get the range v-for feature to display the correct amount of components after the onChange event on the select field.
@HusamIbrahim Indeed the root cause was the selected value is a string, not a number. Updated the answer.
Good catch @JimB.
@JimB. OP could also use the .number modifier for v-model to automatically cast the input to a number.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.