javascript - template - [Advertencia de Vue]: la propiedad o método no está definido en la instancia, sino que se hace referencia durante el render
vue router (1)
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];
}
}
});
Con el código anterior, el error a continuación ocurre cuando se hace clic en el botón.
[Vue warn]: la propiedad o método "changeSetting" no está definido en la instancia, sino que se hace referencia durante el renderizado. Asegúrese de declarar propiedades de datos reactivos en la opción de datos. (encontrado en
<MainTable>
)
Problema
[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>)
El error ocurre porque el método
changeSetting
está siendo referenciado en el componente
MainTable
aquí:
"<button @click=''changeSetting(index)''> Info </button>" +
Sin embargo, el método
changeSetting
no está definido en el componente
MainTable
.
Se está definiendo en el componente raíz aquí:
var app = new Vue({
el: "#settings",
data: data,
methods: {
changeSetting: function(index) {
data.settingsSelected = data.settings[index];
}
}
});
Lo que debe recordarse es que las propiedades y los métodos solo pueden referenciarse en el ámbito donde se definen.
Todo en la plantilla principal se compila en el ámbito principal; todo en la plantilla secundaria se compila en el ámbito secundario.
Puede leer más sobre el alcance de la compilación de componentes en la documentation de Vue.
¿Qué puedo hacer al respecto?
Hasta ahora se ha hablado mucho sobre la definición de las cosas en el ámbito correcto, por lo que la solución es solo mover la definición
MainTable
componente
MainTable
.
Parece así de simple, pero esto es lo que recomiendo.
Probablemente desee que su componente
MainTable
sea un componente tonto / presentacional.
(
Here
hay algo para leer si no sabe qué es sino un tl; dr es que el componente solo es responsable de representar algo, sin lógica).
El elemento inteligente / contenedor es responsable de la lógica: en el ejemplo dado en su pregunta, el componente raíz sería el componente inteligente / contenedor.
Con esta arquitectura, puede utilizar los métodos de comunicación padre-hijo de Vue para que los componentes interactúen.
MainTable
los datos de
MainTable
través de
props
y emite acciones de usuario de
MainTable
a su padre a través de
events
.
Podría verse más o menos así:
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
},
},
}),
Lo anterior debería ser suficiente para darle una buena idea de qué hacer y comenzar a resolver su problema.