vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core

Home Page:http://v2.vuejs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Vue 2.0+ v-for. Getting a 'Property or method is not defined on the instance but referenced during render` error

netpoe opened this issue · comments

commented

I'm getting a 'Property or method is not defined` error:

[Vue warn]: Property or method "genre" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. 
(found in root instance)
[Vue warn]: Error when rendering root instance
TypeError: Cannot read property 'key' of undefined(…)

While using a v-for="(genre, $index) in formFieldData.options":

<body id="vue-wrapper">
<music-genre-id></music-genre-id>

<script type="text/x-template" id="music-genre-id">
    <div class="grid-3">
        <article v-for="(genre, $index) in formFieldData.options">
            <span>{{ genre.key }}</span>
        </article>
    </div>
</script>

<script src="/js/third-party/vue.js"></script>
<script>
    var MusicGenreId = {
        template: '#music-genre-id',
        data: function(){
            return {
                formFieldData: {"id":"music_genre_id","value":null,"type":"select","options":[{"key":"1","value":"M\u00fasica latina","img":"\/img\/music-genres\/latino.jpg"},{"key":"2","value":"Pop","img":"\/img\/music-genres\/pop.jpg"}]},
            }
        },
        ready: function(){},
        methods: {}
    };
    Vue.component('music-genre-id', MusicGenreId);
</script>
<script>
            var vuejs = new Vue({
              el: '#vue-wrapper',
              data: {},
              ready: function(){},
              methods: {}
            });
</script>
</body>

The thing is that I used to have this kind of code in VueJS <2.0 and it worked, except for the (genre, $index) in ... of course.

How can I solve this? I need the formFieldData to be part of the component as it does not belong to the parent/root instance.

FYI
If I do only:

<music-genre-id></music-genre-id>

<script type="text/x-template" id="music-genre-id">
    <div class="grid-3">
        <article v-for="(genre, $index) in formFieldData.options">
            <span>{{ genre }}</span>
        </article>
    </div>
</script>

The browser displays:

{ "key": "1", "value": "Música latina", "img": "/img/music-genres/latino.jpg" }
{ "key": "2", "value": "Pop", "img": "/img/music-genres/pop.jpg" }

But it's not getting the property on {{ genre.key }}

Here's a jsFiddle, check the console.logs to look at the error.

Chrome DevTools VUE Tab shows the <Root> instance with a child <MusicGenreId> component and the component actually displays the data:

formFieldData: {
options: [
{ "key": "1", "value": "Música latina", "img": "/img/music-genres/latino.jpg" },
{ "key": "2", "value": "Pop", "img": "/img/music-genres/pop.jpg" }
]
}

You should not put script/x-template tages inside of the element that you mount to the main instance to. Vue 2.0 will read all of its content and try to use it as a template for the main instance, and Vue's virtualDOM treats script/x-template's like normal DOM, which screws everthing up,

Simply moving the template out of the main element solved the problem.

https://jsfiddle.net/fuefb1x3/1/

Man, thanks... I spent 2 days with this and now your answer saved me. <3