189 votes

[Avertissement Vue] : Une propriété ou une méthode n'est pas définie dans l'instance mais est référencée pendant le rendu.

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];
    }
  }
});

Avec le code ci-dessus, l'erreur ci-dessous se produit lorsque le bouton est cliqué.

[Avertissement Vue] : La propriété ou méthode "changeSetting" n'est pas définie sur l'instance mais référencée pendant le rendu. Assurez-vous de déclarer les propriétés de données réactives dans l'option de données. (trouvé dans <MainTable> )

0 votes

Votre composant n'a pas accès aux méthodes définies sur votre Vue. Vous devez ajouter la méthode changeSetting à la MainTable composant.

149voto

Wing Points 2317

Problème

[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>)

L'erreur se produit parce que le changeSetting est référencée dans la méthode MainTable composant ici :

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

Toutefois, le changeSetting n'est pas définie dans la méthode MainTable composant. Il est défini ici dans le composant Root :

var app = new Vue({
  el: "#settings",
  data: data,
  methods: {
    changeSetting: function(index) {
      data.settingsSelected = data.settings[index];
    }
  }
});

Ce qu'il faut retenir, c'est que les propriétés et les méthodes ne peuvent être référencées que dans la portée où elles sont définies.

Tout ce qui se trouve dans le modèle parent est compilé dans la portée parent ; tout ce qui se trouve dans le modèle enfant est compilé dans la portée enfant.

Vous pouvez en savoir plus sur la portée de la compilation des composants dans le manuel de Vue. documentation .

Qu'est-ce que je peux faire ?

Jusqu'à présent, il a été beaucoup question de définir les choses dans le bon champ d'application. changeSetting dans le MainTable composant ?

Cela semble si simple, mais voici ce que je recommande.

Vous voudriez probablement que votre MainTable pour être un composant muet/de présentation. ( Ici est à lire si vous ne savez pas ce que c'est, mais en résumé, le composant est juste responsable du rendu - pas de logique). L'élément smart/container est responsable de la logique - dans l'exemple donné dans votre question, le composant Root serait le composant smart/container. Avec cette architecture, vous pouvez utiliser les méthodes de communication parent-enfant de Vue pour faire interagir les composants. Vous transmettez les données pour MainTable via accessoires et émettent des actions utilisateur à partir de MainTable à son parent via événements . Cela pourrait ressembler à quelque chose comme ceci :

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
    },
  },
}),

Ce qui précède devrait suffire à vous donner une bonne idée de ce qu'il faut faire et à lancer la résolution de votre problème.

4 votes

Est-ce l'approche la plus privilégiée actuellement ? Les choses évoluent beaucoup dans Vue, alors je me suis dit que je pourrais demander

0 votes

Je ne suis pas un expert de Vue, mais stackoverflow.com/questions/43292810/ suggère que vous pouvez appeler la fonction de l'application à partir de votre composant via $root . Par exemple this.$root.changeSetting(value) directement à partir du composant changeSetting(..) dans ce cas. Ça me semble plus pratique...

1 votes

@Aseem : séparer les préoccupations du code pour rendre les choses plus faciles à comprendre et à modifier est intemporel. La méthode décrite dans la réponse sépare la préoccupation des données et la préoccupation de la présentation de ces données et n'est qu'un exemple de la façon dont les choses peuvent être faites. Je n'évaluerais pas l'approche pour savoir si elle est "actuelle", mais si elle rend le code plus facile à modifier et à comprendre.

62voto

tno2007 Points 41

Si quelqu'un se retrouve avec le même problème que moi, assurez-vous que votre composant possède l'attribut ' données La propriété " est correctement orthographiée. (ex. données et non date )

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

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

40voto

frankfurt-laravel Points 675

Dans mon cas, la raison était que j'ai seulement oublié la fermeture.

</script>

étiquette.

Mais cela a provoqué le même message d'erreur.

15voto

Chuks Jr. Points 63

Si vous rencontrez ce problème, vérifiez que vous n'avez pas

methods: {
...
}

ou

computed: {
...
}

déclaré deux fois

9voto

luigi7up Points 973

N'oubliez pas de rendre la propriété

Une autre raison de voir le La propriété "search" a été accédée pendant le rendu mais n'est pas définie dans l'instance. c'est lorsque vous oubliez de renvoyer la variable dans la section setup(){} fonction

N'oubliez donc pas d'ajouter l'instruction de retour à la fin :

export default {

  setup(){

    const search = ref('')
    //Whatever code

    return {search}

  }
}

Remarque : j'utilise l'API de composition

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X