Ответ 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
},
},
}),
Вышеупомянутое должно быть достаточно, чтобы дать вам хорошее представление о том, что делать, и кикстарта, разрешающего вашу проблему.