Подтвердить что ты не робот

[Vue warn]: свойство или метод не определены в экземпляре, но указаны во время рендеринга

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

4b9b3361

Ответ 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>)

Ошибка возникает, поскольку метод changeSetting ссылается на компонент MainTable:

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

Однако метод changeSetting не определен в компоненте MainTable. Здесь он определяется в корневом компоненте:

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

Что нужно помнить, так это то, что свойства и методы могут быть указаны только в области, где они определены.

Все в родительском шаблоне скомпилировано в родительской области; все в дочернем шаблоне компилируется в области содержимого.

Подробнее о области компиляции компонентов вы можете узнать в Vue документации.

Что я могу сделать с этим?

До сих пор было много разговоров об определении вещей в правильной области, поэтому исправление заключается только в том, чтобы переместить определение changeSetting в компонент MainTable?

Кажется, это просто, но вот то, что я рекомендую.

Вероятно, вы хотите, чтобы ваш компонент MainTable был немым/презентационным компонентом. ( Здесь есть что прочитать, если вы не знаете, что это такое, но tl; dr заключается в том, что компонент просто отвечает за визуализацию - нет логики). Элемент smart/container отвечает за логику - в примере, указанном в вашем вопросе, корневой компонент будет компонентом smart/container. С помощью этой архитектуры вы можете использовать Vue-родительские-дочерние методы связи для взаимодействия компонентов. Вы передаете данные для MainTable через props и выпустите действия пользователя от MainTable до своего родителя с помощью events. Это может выглядеть примерно так:

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

Вышеупомянутое должно быть достаточно, чтобы дать вам хорошее представление о том, что делать, и кикстарта, разрешающего вашу проблему.