[Vue warn]: La propiedad o el método no están definidos en la instancia, pero se hace referencia a ellos durante el renderizado


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 se produce cuando se hace clic en el botón.

[Vue warn]: La propiedad o método "changeSetting" no está definida en la instancia, sino referenciada durante el renderizado. Asegúrese de declarar propiedades de datos reactivos en la opción datos. (encontrado en <MainTable>)

Author: Wing, 2017-03-20

1 answers

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 está ocurriendo 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 ser referenciados en el ámbito donde están definidos.

Todo en la plantilla padre es compilado en el ámbito padre; todo en la plantilla hija se compila en el ámbito hijo.

Puede leer más sobre el ámbito de compilación de componentes en la documentación de Vue .

¿Qué puedo hacer al respecto?

Hasta ahora se ha hablado mucho de definir las cosas en el ámbito correcto, por lo que la solución es solo mover la definición changeSetting en el componente MainTable?

Parece así de simple, pero esto es lo que recomiendo.

Probablemente desea que su componente MainTable sea un componente tonto/presentacional. ( Aquí es algo para leer si no sabes lo que es sino un tl;dr es que el componente es solo responsable de renderizar algo, sin lógica). El elemento smart / container es responsable de la lógica – en el ejemplo dado en su pregunta el componente raíz sería el componente smart/container. Con esta arquitectura puede utilizar los métodos de comunicación padre-hijo de Vue para que los componentes interactúen. Pasar baja los datos de MainTablevía props y emite acciones de usuario desde MainTablea su padre vía eventos . Podría verse algo como esto:

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.

 42
Author: Wing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-20 17:24:08