[Vue warn]: la propiedad o el método no está definido en la instancia, pero se hace referencia durante el procesamiento

95
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 siguiente error ocurre cuando se hace clic en el botón.

[Vue warn]: la propiedad o método "changeSetting" no está definido en la instancia, pero se hace referencia a él durante el renderizado. Asegúrese de declarar las propiedades de los datos reactivos en la opción de datos. (encontrado en <MainTable>)

Lorenzo D'Isidoro
fuente
Su componente no tiene acceso a los métodos definidos en su Vue. Debe agregar el método changeSettingal MainTablecomponente.
Bert

Respuestas:

95

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 se produce porque aquí changeSettingse hace referencia al método en el MainTablecomponente:

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

Sin embargo, el changeSettingmétodo no está definido en el MainTablecomponente. Aquí se define en el componente raíz:

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 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 documentación de Vue .

¿Qué puedo hacer al respecto?

Hasta ahora se ha hablado mucho sobre definir las cosas en el alcance correcto, por lo que la solución es solo mover la changeSettingdefinición al MainTablecomponente.

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

Probablemente desee que su MainTablecomponente sea un componente tonto / de presentación. ( Aquí hay algo para leer si no sabe qué es, pero un tl; dr es que el componente es solo responsable de renderizar 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 entre padres e hijos de Vue para que los componentes interactúen. Usted pasa los datos a MainTabletravés de accesorios y emite acciones de usuario desde MainTablesu padre a través de 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.

Ala
fuente
3
¿Es este el enfoque más preferido actualmente? Las cosas siguen evolucionando mucho en Vue, así que pensé que preguntaría
Aseem
18

Si alguien aterriza con el mismo problema tonto que tuve, asegúrese de que su componente tenga la propiedad ' data ' escrita correctamente. (por ejemplo , datos y no fecha )

<template>
    <span>{{name}}</span>
</template>

<script>
export default {
  name: "MyComponent",
  data() {
    return {
      name: ""
    };
  }
</script>
tno2007
fuente
1
hermano en serio, quiero decir en serio Gracias
Noni
2
Yo aquí en 2020, escribí FECHA
Paaksing el
lmfao este comentario me acaba de salvar
Cris Ravazzano
Lanza el mismo error cuando escribe mal los nombres de sus propiedades. Para mí sucedió porque usé plural datasen la plantilla.
Totymedli
8

En mi caso la razón fue que solo olvidé el cierre

</script>

etiqueta.

Pero eso provocó el mismo mensaje de error.

frankfurt-laravel
fuente
4

Probablemente sea causado por un error ortográfico

Tengo un error tipográfico en la etiqueta de cierre del script

</sscript>
baberos
fuente
3

Si usa dos veces la instancia de vue. Entonces te dará este error. Por ejemplo, en app.js y su propia etiqueta de secuencia de comandos en el archivo de vista. Solo usa una vez

 const app = new Vue({
    el: '#app',
});
Hamza Khan
fuente
2

Añadiendo mi granito de arena también, si alguien tiene problemas como yo, note que métodos es una palabra sensible a mayúsculas y minúsculas:

<template>
    <span>{{name}}</span>
</template>

<script>
export default {
  name: "MyComponent",
  Methods: {
      name() {return '';}
  }
</script>

Los 'métodos' deberían ser 'métodos'

Daniel Katz
fuente
2

Lo más probable es que se trate de un error ortográfico de las variables vuejs reservadas. Llegué aquí porque computed:escribí mal y vuejs no reconocería mis variables de propiedad calculadas. Entonces, si tiene un error como este, ¡primero revise su ortografía!

mahatmanich
fuente
2

Recibí este error cuando intenté asignar una propiedad de componente a una propiedad de estado durante la creación de instancias

export default {
 props: ['value1'],
 data() {
  return {
   value2: this.value1 // throws the error
   }
  }, 
 created(){
  this.value2 = this.value1 // safe
 }
}
Quiero respuestas
fuente
2

Tenía dos methods:en el <script>, va a demostrar, que puedes pasar horas buscando algo que fue un error tan simple.

learncodes123
fuente
2

Mi problema era que estaba colocando los métodos dentro de mi objeto de datos. simplemente formatéelo así y funcionará bien.

<script>
module.exports = {
    data: () => {
        return {
            name: ""
        }
    },
    methods: {
        myFunc() {
            // code
        }
    }
}
</script>
Fantástico
fuente
2

Si tiene este problema, asegúrese de que no tiene

methods: {
...
}

o

computed: {
...
}

declarado dos veces

Chuks Jr.
fuente
1

En mi caso fue una propiedad la que me dio el error, la escritura correcta y aun así me dio el error en la consola. Busqué mucho y nada me funcionó, hasta que le di Ctrl + F5 y ¡Voilá! se eliminó el error. : 'v

Jennifer Miranda Beuses
fuente