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>
)
[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.
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.
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.
[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:
[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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With