1

I found nothing around the web. What I was wondering is if it is possible to use the v-for directive inside the template of a custom component. Here is what I have done:

HTML

 <div id="macroservizi" class="col-lg-12 col-xs-12 collapse" v-if="modello">
 <lista-servizi :servizi="modello"></lista-servizi>
 </div>

CUSTOM COMPONENT

Vue.component('lista-servizi', {
template:
 '<div id="tuttiGialla" class="collapse">'+
 '<template class="servizioInlista">'+
 '<div class="row" v-for="(single,index) in servizi.lineaGialla.servizi" :key="single.nomeServizio">'+
 '<div class="col-lg-8 col-xs-8 nopadding">'+
 '<h4 class="blu">{{single.nomeServizio}} {{index}}</h4>'+
 '</div>'+
 '<div class="col-lg-4 col-xs-4>"'+
 '<span class="pull-right nomargin" v-on:click="mostraServiziGiallo(index)" v-bind:class="[GiallaTutti ? \'minus\' : !GiallaTutti,\'plus\']" data-toggle="collapse" data-target="\'#singoloGialla-\'+index"></span>'+ 
 '</div>'+
 '</div>'+
 '<div v-bind:id="\'#singoloGialla-\'+index" class="row">'+
 '<p>{{single.descrizione}}</p>'+
 '</div>'+
 '</template>'+
 '</div>',
 props: ['servizi'],
computed: {
 listaServizi() {
 return this.servizi
 }
}

I have the following errors in the console:

- tag <template> has no matching end tag. found in ---> <ListaServizi>
vue.js:435 [Vue warn]: Property or method "index" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
found in
---> <ListaServizi>
 <Root>
[Vue warn]: Property or method "single" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.

I tried multiple ways to render it, but at this point I wonder if it is even possible.

Bert
82.6k17 gold badges204 silver badges166 bronze badges
asked Jul 11, 2017 at 18:17

1 Answer 1

2

First, v-for works fine in a custom component.

Second, there is no need to use string concatenation to build your template. Use javascript template literals to wrap your template and you can use as many lines as you want.

Here I have tried to clean up your component as best I can understand it.

Vue.component('lista-servizi', {
 template:`
 <div>
 <div id="tuttiGialla" class="collapse">
 <template v-for="(single,index) in servizi.lineaGialla.servizi">
 <div class="row servizioInlista" 
 :key="single.nomeServizio">
 <div class="col-lg-8 col-xs-8 nopadding">
 <h4 class="blu">{{single.nomeServizio}} {{index}}</h4>
 </div>
 <div class="col-lg-4 col-xs-4>">
 <span class="pull-right nomargin" 
 v-on:click="mostraServiziGiallo(index)" 
 v-bind:class="[GiallaTutti ? 'minus' : 'plus']" 
 data-toggle="collapse" 
 data-target="'#singoloGialla-' + index">
 </span> 
 </div>
 </div>
 <div v-bind:id="'#singoloGialla-' + index" class="row">
 <p>{{single.descrizione}}</p>
 </div>
 </template>
 </div>
 </div> 
 `,
 props: ['servizi'],
 computed: {
 listaServizi() {
 return this.servizi
 }
 },
 created(){
 console.log(this.servizi)
 }
})

The main issue here is you were referencing single and index in this part of the template:

<div v-bind:id="'#singoloGialla-' + index" class="row">
 <p>{{single.descrizione}}</p>
</div>

But that code was outside of your v-for. I added the v-for to your template so that that bit of the template is now in scope for the loop iteration.

answered Jul 11, 2017 at 18:35

15 Comments

thank you @Bert Evans, but if i work in this way in the console i find this message:
Uncaught SyntaxError: Invalid or unexpected token
just when the template is declaring
@PdsInk What browser?
@BertEvans your template starts with </div>
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.