Reputation: 2229
The following code has been written to handle an event after a button click
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];
}
}
});
But the following error occurred:
[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>
)
Upvotes: 191
Views: 535429
Reputation: 47
In my case, I had child component called from parent like this:
<bSearch></bSearch>
When I have changed to:
<bSearch/>
Vue warn, which was mentioned in this issue, then disappeared. I am using Vue 3 - composition API in Single file component (SFC). Hope someone will help it.
Upvotes: -2
Reputation: 1048
I want to add one more to the list.
TLDR: make sure you are making changes in the correct file
Context:
I am working in a codebase that we inherited from another company and I continued to get that error. Then I noticed there were two files with similar names: search-bar.js
and search-bar.vue.js
. The code in both files is Vue code. However, as soon as I moved my code into the other file everything started working as expected. Silly, I know, but still something worth calling out.
Upvotes: 0
Reputation: 31
In my case it was the methods: { }
I had put the }
before my method functions so for example I had it like this methods: { function , function }, function, function
so some of the functions that were out of the curly braces were not included inside the methods function.
Upvotes: 1
Reputation: 61
For me it happened because I wrote method:
instead of methods:
(plural). It's a silly mistake but it can happen :)
Upvotes: 0
Reputation: 2168
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>
Upvotes: 63
Reputation: 27053
One other common scenario is:
xyz
defined under methods
or computed
on the parent component.xyz
, but your child component defines its own methods
or computed
// PARENT COMPONENT
export default {
computed() {
abc() {},
xyz() {} // <= needs to be used in child component
},
...
}
// CHILD COMPONENT
export default {
extends: myParentComponent,
computed() {
childProprty1() {},
childProprty2() {}
}
}
In this case you will need to redefine your xyz
computed property under computed
Redefine xyz
and copy the code from the parent component
// CHILD COMPONENT
export default {
extends: myParentComponent,
computed() {
xyz() {
// do something cool!
},
childProprty1() {},
childProprty2() {}
}
}
Redefine xyz
property reusing parent component code (no code redundancy)
// CHILD COMPONENT
export default {
extends: myParentComponent,
computed() {
xyz() {
return this.$parent.$options.computed.xyz
},
childProprty1() {},
childProprty2() {}
}
}
Upvotes: 0
Reputation: 46794
Most people do have an error here because of:
To avoid the typo issues, I recommend always using Vue VSCode Snippets so that you don't write anything by hand by rather use vbase
, vdata
, vmethod
and get those parts generated for you.
Here are the ones for Vue3.
You can of course also create your own snippets by doing the following.
Also make sure that you're properly writing all the correct names as shown here, here is a list:
As for the second part, I usually recommend either searching the given keyword in your codebase. So like cmd + f + changeSetting
in OP's case to see if it's missing a declaration somewhere in data
, methods
or alike.
Or even better, use an ESlint configuration so that you will be warned in case you have any kind of issues in your codebase.
Here is how to achieve such setup with a Nuxt project + ESlint + Prettier for the most efficient way to prevent bad practices while still getting a fast formatting!
Upvotes: 0
Reputation: 1917
It seems there are many scenarios that can trigger this error. Here's another one which I just resolved.
I had the variable actionRequiredCount declared in the data section, but I failed to capitalize the C in Count when passing the variable as a params to a component.
Here the variable is correct:
data: () => {
return{
actionRequiredCount: ''
}
}
In my template it was incorrect (notd the no caps c in "count"):
<MyCustomModule :actionRequiredCount="actionRequiredcount"/>
Hope this helps someone.
Upvotes: 0
Reputation: 9731
[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.
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.
Upvotes: 151
Reputation: 3046
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.
Upvotes: 0
Reputation: 194
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;
}
Upvotes: 2
Reputation: 1087
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
Upvotes: 2
Reputation: 8063
Upvotes: 3
Reputation: 2364
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.
Upvotes: 0
Reputation: 330
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;
}
}
Upvotes: 1
Reputation: 61
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}}"
Upvotes: 0
Reputation: 3082
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 !
Upvotes: 1
Reputation: 1443
In my case, I wrote it as "method" instead of "methods". So stupid. Wasted around 1 hour.
Upvotes: 3
Reputation: 5962
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
Upvotes: 9
Reputation: 503
If you're experiencing this problem, check to make sure you don't have
methods: {
...
}
or
computed: {
...
}
declared twice
Upvotes: 15
Reputation: 737
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
Upvotes: 1
Reputation: 481
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>
Upvotes: 4
Reputation: 401
I had two methods:
in the <script>
, goes to show, that you can spend hours looking for something that was such a simple mistake.
Upvotes: 2
Reputation: 441
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
}
}
Upvotes: 4
Reputation: 99
It's probably caused by spelling error
I got a typo at script closing tag
</sscript>
Upvotes: 8
Reputation: 361
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',
});
Upvotes: 4
Reputation: 4131
In my case the reason was, I only forgot the closing
</script>
tag.
But that caused the same error message.
Upvotes: 40
Reputation: 11033
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!
Upvotes: 2
Reputation: 2408
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'
Upvotes: 5