user9982219
user9982219

Reputation:

Vue: the template root disallows v-for directives

I'm trying to make a simple post list component, where I use the v-for directive, but I'm seeing the following error:

"eslint-eslint: the template root disallows v-for directives"

How am I supposed to loop and render each post?

I'm passing allBehaviourPosts to the component from a Laravel backend as a prop, like this:

<related-post-list :relatedBehaviourPost= {{ $relatedBehaviourPosts }}></>

My component:

<template>
<div class="sidebar_related_content_container" v-for="behaviour in relatedBehaviourPosts " :key="behaviour.id" style="">
    <a class="sidebar_related_content_image" href="/conducta-canina/{{ relatedBehaviour.slug }}"  style="background-image:url('{{ behaviour.image }}');">
        <div class="black_gradient" style=""></div>
    </a>
    <div class="sidebar_related_content_text_container" style="">
        <span class="sidebar_related_content_text_title" style="">{{ behaviour.postcategory.name }}</span>
        <span class="sidebar_related_content_text_description" style="">{{ behaviour.title }}</span>
    </div>
</div>
</template>
<!--SCRIPTS-->
<script>
    export default {

        props: ['relatedBehaviourPosts'],

        data: function () {
            return {
                //data
            }
        },

        mounted() {
            console.log('Footer mounted.')
        }
    }
</script>
<!--STYLES-->
<style scoped>

</style>

Upvotes: 19

Views: 27098

Answers (2)

tony19
tony19

Reputation: 138326

In Vue 2, each component can only contain a single root element, which precludes conditional rendering or list rendering on the root element. You would have to wrap your list in another element (e.g., a div), making that the root:

<template>
  <div> <!-- single root element here -->

    <div v-for="behaviour in relatedBehaviourPosts " :key="behaviour.id">
      <!-- ... -->
    </div>

  </div>
</template>

Also note Vue 2 does not support string interpolation in attribute bindings, so those would have to be replaced with data bindings of this syntax:

:ATTRIBUTE_NAME="VALUE"

In particular, replace this:

<a href="/conducta-canina/{{ behaviour.slug }}"
   style="background-image:url('{{ behaviour.image }}');"></a> <!-- DON'T DO THIS -->

with this (using ES2015 template literals):

<a :href="`/conducta-canina/${behaviour.slug}`"
   :style="`background-image:url('${behaviour.image}');`"></a>

or with this (using string concatenation):

<a :href="'/conducta-canina/' + behaviour.slug"
   :style="'background-image:url(\'' + behaviour.image + '\');'"></a>

Vue 2 demo

Note that Vue 3 allows multiple root nodes, so your component template would work there.

Upvotes: 37

David Dennis
David Dennis

Reputation: 41

I got this error sometimes ago, the problem is that the template root does not allow 'v-for' directives. The solution to use directives in a template is, you need to provide a root div to contain the element that has your directives. This worked in my case. Check here for more info https://eslint.vuejs.org/rules/valid-template-root.html

<template>
<!-- place a root element -->
<div>
 <div v-for='item in menu'>some items</div>
</div>
</template>

Upvotes: 4

Related Questions