問題
[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は構成要素が何かのレンダリングのためだけの責任があるということである-ノーロジック)。スマート/コンテナ要素がロジックを担当します。質問の例では、ルートコンポーネントはスマート/コンテナコンポーネントになります。このアーキテクチャでは、コンポーネントが相互作用するためにVueの親子通信方法を使用できます。小道具をMainTable
介してデータを渡し、イベントを介して親にユーザーアクションを送信します。次のようになります。MainTable
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) {
},
},
}),
上記は、何をすべきかについての良いアイデアを与え、問題の解決を開始するのに十分なはずです。
changeSetting
にMainTable
コンポーネント。