简体   繁体   中英

Vue.js v-for with extra li doesn't render

I have a ul with items coming from the loop, and then extra li after that.

<ul>
  <todo-item v-for="(todo,index) in todos" v-bind:todo="todo" :key="index" />
  <li :key='"new_item"'>
    <input placeholder="What needs to be done?" type="text" v-model="new_todo" >
    <button v-on:click="add_todo()">Add</button>
  </li>
</ul>  

This doesn't show the extra line. But if I switch it so extra li is first it does.

<ul>
  <li :key='"new_item"'>
    <input placeholder="What needs to be done?" type="text" v-model="new_todo" >
    <button v-on:click="add_todo()">Add</button>
  </li>
  <todo-item v-for="(todo,index) in todos" v-bind:todo="todo" :key="index" />
</ul>  

So I'm probably doing something wrong with key, but I can't find what exactly.

The whole code is here .

The problem is that vue components require a closing tag and won't work properly just with self-closing tags.

Try like that:

<ul>
  <todo-item v-for="(todo,index) in todos" v-bind:todo="todo" :key="index"></todo-item>
  <li :key='"new_item"'>
    <input placeholder="What needs to be done?" type="text" v-model="new_todo" >
    <button v-on:click="add_todo()">Add</button>
  </li>
</ul>  

From the official Vue Style Guide :

Components that self-close communicate that they not only have no content, but are meant to have no content. It's the difference between a blank page in a book and one labeled “This page intentionally left blank.” Your code is also cleaner without the unnecessary closing tag.

Unfortunately, HTML doesn't allow custom elements to be self-closing - only official “void” elements. That's why the strategy is only possible when Vue's template compiler can reach the template before the DOM, then serve the DOM spec-compliant HTML.

You are not allowed to use self-closing tags, so instead of <todo-item /> use <todo-item></todo-item>

https://github.com/vuejs/vue/issues/1036

Not a valid HTML5 components it seems.

Do you use SFC or usual HTML files? Maybe the problem is that HTML parser doesn't allow to use <todo-item> inside <ul> . Try to use <li :is="'todo-item'" v-for...> instead (it's works in your codepen)

<div id="app">
  <h1>TODOs</h1>
  <ul>
    <li :is="'todo-item'" v-for="(todo,index) in todos" v-bind:todo="todo" :key="index"></li>
    <li :key='"new_item"'>
      <input placeholder="What needs to be done?" type="text" v-model="new_todo" >
      <button v-on:click="add_todo()">Add</button>
    </li>
  </ul>  
  <p>You have finished {{ done }}/{{ total }}</p>
</div>

https://v2.vuejs.org/v2/guide/components.html#DOM-Template-Parsing-Caveats

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM