ChatGPT解决这个技术问题 Extra ChatGPT

[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 )

Your component does not have access to methods defined on your Vue. You need to add the method changeSetting to the MainTable component.

t
tony19

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 )

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.


Is this the most preferred approach currently? Things keep evolving a lot in Vue so I though I would ask
I'm no expert in Vue, but stackoverflow.com/questions/43292810/… suggests you can call app's function from your component via $root. E.g. this.$root.changeSetting(value) directly from component's changeSetting(..) in this case. Looks more convenient to me...
@Aseem: separating concerns of code to make things easier to understand and change is timeless. The method described in the answer separates the concern of data and the concern of presenting that data and is just one example of how things might be done. I would not evaluate the approach as to if it is 'current' but whether it makes code easier to change and understand.
@FlasHfromRu: You can reference things from $root but in general it is not a good idea. See this note on accessing root instances from Vue's documentation: "This can be convenient for demos or very small apps with a handful of components. However, the pattern does not scale well to medium or large-scale applications, so we strongly recommend using Vuex to manage state in most cases."
t
tno2007

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>

Me here in 2020, I wrote DATE
lmfao this comment just saved me
Should anybody land with the same silly problem I had, make sure your component has the 'data' property spelled correctly. Lol really a very siilly problem :) thanks man
This comment saved me! I had "computed" defined within with the "data" property.
Vue would be do much better without all of these gotchas...
f
frankfurt-laravel

In my case the reason was, I only forgot the closing

</script>

tag.

But that caused the same error message.


Dude... that was it! I would have never found this.
Unexpected, my some hours error is this one :)
OMFG THANK YOU!
Thank you. I looked all over before finding this solution.
i love you xD.... same error!!!
b
bibs

It's probably caused by spelling error

I got a typo at script closing tag

</sscript>

This or bad naming convention: I had the error trying to call fileList but the data property was filelist.
C
Chuks Jr.

If you're experiencing this problem, check to make sure you don't have

methods: {
...
}

or

computed: {
...
}

declared twice


Holy moly! I got this and I didn't know it
thank you! I've been freaking out on this!
l
luigi7up

Remember to return the property

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

So remember to add the return statement at the end:

export default {

  setup(){

    const search = ref('')
    //Whatever code

    return {search}

  }
}

Note: I'm using the Composition API


D
Daniel Katz

Adding my bit as well, should anybody struggle like me, notice that methods is a case-sensitive word:

<template>
    <span>{{name}}</span>
</template>

<script>
export default {
  name: "MyComponent",
  Methods: {
      name() {return '';}
  }
</script>

'Methods' should be 'methods'


in my case, I had method LOL
Same here, I had "method" instead of "methods". It would be good if Vue or linters can pick this up at compile time.
I
I Want Answers

I got this error when I tried assigning a component property to a state property during instantiation

export default {
 props: ['value1'],
 data() {
  return {
   value2: this.value1 // throws the error
   }
  }, 
 created(){
  this.value2 = this.value1 // safe
 }
}

if you don't have any typo this is the best anwer!
P
Pwntastic

My issue was I was placing the methods inside my data object. just format it like this and it'll work nicely.

<script>
module.exports = {
    data: () => {
        return {
            name: ""
        }
    },
    methods: {
        myFunc() {
            // code
        }
    }
}
</script>

W
Watercayman

If you use two times vue instance. Then it will give you this error. For example in app.js and your own script tag in view file. Just use one time

 const app = new Vue({
    el: '#app',
});

B
Balasubramanian S

In my case, I wrote it as "method" instead of "methods". So stupid. Wasted around 1 hour.


Thank you so much for this! This was driving me insane.
I wrote date() instead of data()
m
mahatmanich

It is most likely a spelling error of reserved vuejs variables. I got here because I misspelled computed: and vuejs would not recognize my computed property variables. So if you have an error like this, check your spelling first!


l
learncodes123

I had two methods: in the <script>, goes to show, that you can spend hours looking for something that was such a simple mistake.


M
MD SHAYON

Some common cases of this error

Make sure your component has the data property spelled correctly

Make sure your template is bot defined within another component’s template.

Make sure you defined the variable inside data object

Make sure your router name in string

Get some more sollution


Nice summary! Also double check the function name matches: :class="boxAClasses" vs boxAclasses() { … }
J
Jennifer Miranda Beuses

In my case it was a property that gave me the error, the correct writing and still gave me the error in the console. I searched so much and nothing worked for me, until I gave him Ctrl + F5 and Voilá! error was removed. :'v


m
marcdahan

Look twice the warning : Property _____ was accessed during render but is not defined on instance. So you have to define it ... in the data function for example which commonly instantiate variables in a Vuejs app. and, it was my case and that way the problem has been fixed. That's all folk's !


T
Toni

In my case, I forgot to add the return keyword:

computed: {
    image(){
        this.productVariants[this.selectedVariant].image;
    },
    inStock(){
       this.productVariants[this.selectedVariant].quantity;
    }
}

Change to:

computed: {
    image(){
        return this.productVariants[this.selectedVariant].image;
    },
    inStock(){
       return this.productVariants[this.selectedVariant].quantity;
    }
}


L
Lepy

if you have any props or imported variables (from external .js file) make sure to set them properly using created like this;

make sure to init those vars:

import { var1, var2} from './constants'

//or

export default {
     data(){
      return {
       var1: 0,
       var2: 0,
       var3: 0,
      },
    },
    props: ['var3'],
    created(){
     this.var1 = var1;
     this.var2 = var2;
     this.var3 = var3;
     }
    

f
fahd shaykh

In my case due to router name not in string:

:to="{name: route-name, params: {id:data.id}}"

change to router name in string:

:to="{name: 'router-name', params: {id:data.id}}"

a
aarkerio

In my case I was trying to pass a hard coded text value to another component with:

 ChildComponent(:displayMode="formMode")

when it should be:

ChildComponent(:displayMode="'formMode'")

note the single quotes to indicate text instead of calling a local var inside the component.


If you want to pass String value to component then you could do it like this displayMode="formMode". Note: We are not binding using v-bind and therefore displayMode will store String value
C
Charles Brandt

If you're using the Vue3 <script setup> style, make sure you've actually specified setup in the opening script tag:

<script setup>

I had lapsed into old habits and only created a block with <script>, but it took a while to notice it.

https://v3.vuejs.org/api/sfc-script-setup.html


G
Gel

Although some answers here maybe great, none helped my case (which is very similar to OP's error message).

This error needed fixing because even though my components rendered with their data (pulled from API), when deployed to firebase hosting, it did not render some of my components (the components that rely on data).

To fix it (and given you followed the suggestions in the accepted answer), in the Parent component (the ones pulling data and passing to child component), I did:

// pulled data in this life cycle hook, saving it to my store
created() {
  FetchData.getProfile()
    .then(myProfile => {
      const mp = myProfile.data;
      console.log(mp)
      this.$store.dispatch('dispatchMyProfile', mp)
      this.propsToPass = mp;
    })
    .catch(error => {
      console.log('There was an error:', error.response)
    })
}
// called my store here
computed: {
    menu() {
        return this.$store.state['myProfile'].profile
    }
},

// then in my template, I pass this "menu" method in child component
 <LeftPanel :data="menu" />

This cleared that error away. I deployed it again to firebase hosting, and voila!

Hope this bit helps you.


Pardon my being picky (I am French): "and voilà!"
p
pmvp

For me, I just forget to close script tag :-)


r
rico

mine was to re create the component and the error was gone. good thing i was just on the first part. weird. edit: i was using composition api


E
Ewin

First of all check the spelling of your property or method you're trying to access. I spent minutes trying to find a solution, not knowing that the method I was trying to access was mispelled


This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now