[Vue warn]:属性或方法不是在实例上定义的,而是在渲染过程中引用的问题我该怎么办?

2022-08-30 02:22:04
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];
    }
  }
});

使用上面的代码,单击按钮时会发生以下错误。

[Vue warn]:属性或方法“changeSetting”不是在实例上定义的,而是在渲染过程中引用的。确保在数据选项中声明反应式数据属性。(发现于<MainTable>)


答案 1

问题

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

发生此错误的原因是,在以下组件中引用了该方法:changeSettingMainTable

    "<button @click='changeSetting(index)'> Info </button>" +

但是,该方法未在组件中定义。它是在以下根组件中定义的:changeSettingMainTable

var app = new Vue({
  el: "#settings",
  data: data,
  methods: {
    changeSetting: function(index) {
      data.settingsSelected = data.settings[index];
    }
  }
});

需要记住的是,属性和方法只能在定义它们的范围内引用。

父模板中的所有内容都在父范围内编译;子模板中的所有内容都在子作用域中编译。

你可以在 Vue 的文档中阅读有关组件编译范围的更多信息。

我该怎么办?

到目前为止,已经有很多关于在正确范围内定义事物的讨论,所以修复只是将定义移动到组件中?changeSettingMainTable

这似乎很简单,但这是我推荐的。

您可能希望您的组件是一个哑/表示组件。(如果您不知道它是什么,请阅读以下内容,但tl;dr是组件仅负责渲染某些内容 - 没有逻辑)。智能/容器元素负责逻辑 - 在问题中给出的示例中,根组件将是智能/容器组件。有了这个架构,你可以使用 Vue 的父子通信方法让组件进行交互。您将通过 props 传递数据,并通过事件将用户操作从其父发出。它可能看起来像这样:MainTableMainTableMainTable

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
    },
  },
}),

以上应该足以让您很好地了解该怎么做并开始解决问题。


答案 2

如果有人遇到我遇到的同样愚蠢的问题,请确保您的组件具有拼写正确的“data”属性。(例如。数据,而不是日期)

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

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