53

I am a newbie to Vue.js

I am preparing a demo for input elements practices, here is my code.

HTML

<div id="inputDiv">
  <form action="">
    <input type="text" v-model="first_name">
    <input type="text" v-model="last_name">
    <input type="email" v-model="email">
    <div>
      <input type="radio" :name="gender" v-model="gender" value="male">Male
      <input type="radio" :name="gender" v-model="gender" value="female">Female
    </div>
    <textarea v-model="address" id="" cols="30" rows="10"></textarea>
    <br>
    <div v-for="hobby in hobbies">
      <input type="checkbox" v-model="userHobbies" v-bind:value="hobby">{{hobby}}
    </div>
  </form>
</div>

Script

const inputApp = new Vue({
  el: '#inputDiv',
  data: {
    first_name: '',
    last_name: '',
    email: '',
    gender: 'male',
    address: '',
    userHobbies:[],
    hobbies: ['Reading', 'Cricket', 'Cycling', 'Hiking']
  }
})

Here you can see, to display Hobby with label I have to iterate with parent ,

adding a div is not something I want, If I will v-for in input element like:

<input 
  type="checkbox" 
  v-for="hobby in hobbies" 
  v-model="userHobbies" 
  v-bind:value="hobby"
>{{hobby}}

then it's throwing exception [Vue warn]: Property or method "hobby" is not defined on the instance

My question is there any alternative for v-for over object elements without using HTML element?

3 Answers 3

103

Wrap it in a template tag as the template tag will not appear in the final rendered HTML:

<template v-for="hobby in hobbies">
    <input type="checkbox" v-model="userHobbies" v-bind:value="hobby">{{hobby}}
</template>

Or even better, improve your markup semantics and use a label tag:

<label v-for="hobby in hobbies">
    <input type="checkbox" v-model="userHobbies" v-bind:value="hobby"> {{hobby}}
</label>
Sign up to request clarification or add additional context in comments.

Comments

12

You can add template inside of div as template is not rendered to the DOM:

  <div id="inputDiv">
    <form action>
      <input type="text" v-model="first_name">
      <input type="text" v-model="last_name">
      <input type="email" v-model="email">
      <div>
        <input type="radio" :name="gender" v-model="gender" value="male">Male
        <input type="radio" :name="gender" v-model="gender" value="female">Female
      </div>
      <textarea v-model="address" id cols="30" rows="10"></textarea>
      <br>
      <template v-for="hobby in hobbies">
        <input type="checkbox" v-model="userHobbies" v-bind:value="hobby">
        {{hobby}}
      </template>
    </form>
  </div>

Comments

2

The issue is that, the string interpolation {{hobby}} after the tag is outside the loop, which is why the error is shown, in this specific case, you have to wrap it inside something.

If you don't want to specifically use div you can go for label instead which is much more natural in this scenario and now if the user clicks on the label, the checkbox will automatically get selected.

<label v-for="hobby in hobbies">
    <input type="checkbox" v-model="userHobbies" v-bind:value="hobby"> {{hobby}} <br>
</label>

new Vue({
  el: '#inputDiv',
  data: {
    first_name: '',
    last_name: '',
    email: '',
    gender: 'male',
    address: '',
    userHobbies:[],
    hobbies: ['Reading', 'Cricket', 'Cycling', 'Hiking']
  }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="inputDiv">
<form action="">
    <input type="text" v-model="first_name">
    <input type="text" v-model="last_name">
    <input type="email" v-model="email">
    <div>
        <input type="radio" :name="gender" v-model="gender" value="male">Male
        <input type="radio" :name="gender" v-model="gender" value="female">Female
    </div>
    <textarea v-model="address" id="" cols="30" rows="10"></textarea>
    <br>
    <label v-for="hobby in hobbies">
        <input type="checkbox" v-model="userHobbies" v-bind:value="hobby">{{hobby}}
        <br>
    </label>
</form>
{{ userHobbies | json }}
</div>

Comments

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.