[Vue 警告]:属性或方法未在实例上定义但在渲染期间被引用 [英] [Vue warn]: Property or method is not defined on the instance but referenced during render

查看:539
本文介绍了[Vue 警告]:属性或方法未在实例上定义但在渲染期间被引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆