[Vue 警告]:属性或方法未在实例上定义但在渲染期间被引用 [英] [Vue warn]: Property or method is not defined on the instance but referenced during render
问题描述
var MainTable = Vue.extend({模板:"+"- "+"{{索引}})" +"{{set.title}}" +"<button @click='changeSetting(index)'> 信息 </button>"+</li>"+"</ul>",数据:函数(){返回数据;}});Vue.component("主表", MainTable);data.settingsSelected = {};var app = new Vue({el: "#settings",数据:数据,方法: {更改设置:函数(索引){data.settingsSelected = data.settings[index];}}});
使用上面的代码,点击按钮时出现下面的错误.
<块引用>[Vue 警告]:属性或方法changeSetting"未在实例上定义,但在渲染期间被引用.确保在数据选项中声明反应数据属性.(在
中找到)
问题
<块引用>[Vue 警告]:属性或方法changeSetting"未在实例上定义,但在渲染期间被引用.确保在数据选项中声明反应数据属性.(在
发生错误是因为 MainTable
组件中引用了 changeSetting
方法:
"
然而 changeSetting
方法没有在 MainTable
组件中定义.它是在此处的根组件中定义的:
var app = new Vue({el: "#settings",数据:数据,方法: {更改设置:函数(索引){data.settingsSelected = data.settings[index];}}});
需要记住的是,属性和方法只能在定义的范围内被引用.
<块引用>父模板中的所有内容都在父范围内编译;子模板中的所有内容都在子范围内编译.
您可以在 Vue 的文档中阅读有关组件编译范围的更多信息.
我该怎么办?
到目前为止,已经有很多关于在正确范围内定义事物的讨论,所以修复只是将 changeSetting
定义移动到 MainTable
组件中?>
看起来很简单,但这是我推荐的.
您可能希望您的 MainTable
组件是一个哑/展示组件.(这里 如果您不知道什么,请阅读这里只是一个 tl;dr 是组件只负责渲染某些东西 - 没有逻辑).smart/container 元素负责逻辑 - 在您的问题中给出的示例中,根组件将是 smart/container 组件.有了这个架构,你就可以使用Vue的父子通信方式让组件进行交互.您通过 props 传递 MainTable
的数据和通过 eventsMainTable 向其父级发出用户操作一>.它可能看起来像这样:
Vue.component('主表', {模板:"+"<li v-for='(set, index) in settings'>"+"{{索引}})" +"{{set.title}}" +"<button @click='changeSetting(index)'> 信息 </button>"+</li>"+"</ul>",道具:['设置'],方法: {更改设置(值){this.$emit('change', value);},},});var app = new Vue({el: '#settings',模板:'<主表:settings="data.settings"@change="changeSetting"></main-table>',数据:数据,方法: {更改设置(值){//处理更改设置},},}),
以上内容应该足以让您很好地了解该怎么做并开始解决您的问题.
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>
)
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.
这篇关于[Vue 警告]:属性或方法未在实例上定义但在渲染期间被引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!