Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

[Vue warn]: Property or method is not defined on the instance but referenced during render

var MainTable = Vue.extend({   template: "<ul>" +     "<li v-for='(set,index) in settings'>" +     "{{index}}) " +     "{{set.title}}" +     "<button @click='changeSetting(index)'> Info </button>" +     "</li>" +     "</ul>",   data: function() {     return data;   } });  Vue.component("main-table", MainTable);  data.settingsSelected = {}; var app = new Vue({   el: "#settings",   data: data,   methods: {     changeSetting: function(index) {       data.settingsSelected = data.settings[index];     }   } }); 

With the above code, the error below occurs when the button is clicked.

[Vue warn]: Property or method "changeSetting" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in <MainTable>)

like image 816
Lorenzo D'Isidoro Avatar asked Mar 20 '17 16:03

Lorenzo D'Isidoro


People also ask

Why is prop not defined on the instance?

[Vue warn]: Property or method "prop" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

Why is the property search not defined on an instance?

Another reason of seeing the Property "search" was accessed during render but is not defined on instance is when you forget to return the variable in the setup () {} function.

How to fix [Vue warn] property or method is not defined?

To fix [Vue warn]: Property or method is not defined on the instance but referenced during render with Vue.js, we should make sure the reactive property is defined in the component. to add the name reactive property in the object returned by data. Then we can reference name in the template without errors.

Why is the changesetting method not defined in the maintable?

[Vue warn]: Property or method "changeSetting" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in <MainTable>) The error is occurring because the changeSetting method is being referenced in the MainTable component here:


2 Answers

Problem

[Vue warn]: Property or method "changeSetting" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in <MainTable>)

The error is occurring because the changeSetting method is being referenced in the MainTable component here:

    "<button @click='changeSetting(index)'> Info </button>" + 

However the changeSetting method is not defined in the MainTable component. It is being defined in the root component here:

var app = new Vue({   el: "#settings",   data: data,   methods: {     changeSetting: function(index) {       data.settingsSelected = data.settings[index];     }   } }); 

What needs to be remembered is that properties and methods can only be referenced in the scope where they are defined.

Everything in the parent template is compiled in parent scope; everything in the child template is compiled in child scope.

You can read more about component compilation scope in Vue's documentation.

What can I do about it?

So far there has been a lot of talk about defining things in the correct scope so the fix is just to move the changeSetting definition into the MainTable component?

It seems that simple but here's what I recommend.

You'd probably want your MainTable component to be a dumb/presentational component. (Here is something to read if you don't know what it is but a tl;dr is that the component is just responsible for rendering something – no logic). The smart/container element is responsible for the logic – in the example given in your question the root component would be the smart/container component. With this architecture you can use Vue's parent-child communication methods for the components to interact. You pass down the data for MainTable via props and emit user actions from MainTable to its parent via events. It might look something like this:

Vue.component('main-table', {   template: "<ul>" +     "<li v-for='(set, index) in settings'>" +     "{{index}}) " +     "{{set.title}}" +     "<button @click='changeSetting(index)'> Info </button>" +     "</li>" +     "</ul>",   props: ['settings'],   methods: {     changeSetting(value) {       this.$emit('change', value);     },   }, });   var app = new Vue({   el: '#settings',   template: '<main-table :settings="data.settings" @change="changeSetting"></main-table>',   data: data,   methods: {     changeSetting(value) {       // Handle changeSetting     },   }, }), 

The above should be enough to give you a good idea of what to do and kickstart resolving your issue.

like image 81
Wing Avatar answered Sep 18 '22 13:09

Wing


Should anybody land with the same silly problem I had, make sure your component has the 'data' property spelled correctly. (eg. data, and not date)

<template>     <span>{{name}}</span> </template>  <script> export default {   name: "MyComponent",   data() {     return {       name: ""     };   } </script> 
like image 22
tno2007 Avatar answered Sep 22 '22 13:09

tno2007