[Vue warn]: Eigenschaft oder Methode ist nicht für die Instanz definiert, sondern wird beim Rendern referenziert

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

Mit dem obigen Code tritt der folgende Fehler auf, wenn auf die Schaltfläche geklickt wird.

[Vue warn]: Die Eigenschaft oder Methode "changeSetting" ist nicht für die Instanz definiert, sondern wird beim Rendern referenziert. Stellen Sie sicher, dass in der Datenoption reaktive Dateneigenschaften deklariert sind. (gefunden in <MainTable>)

Lorenzo D'Isidoro
quelle
Ihre Komponente hat keinen Zugriff auf Methoden, die in Ihrem Vue definiert sind. Sie müssen die Methode changeSettingzur MainTableKomponente hinzufügen .
Bert

Antworten:

93

Problem

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

Der Fehler tritt auf, weil hier changeSettingin der MainTableKomponente auf die Methode verwiesen wird :

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

Die changeSettingMethode ist jedoch nicht in der MainTableKomponente definiert . Es wird hier in der Root-Komponente definiert:

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

Zu beachten ist, dass Eigenschaften und Methoden nur in dem Bereich referenziert werden können, in dem sie definiert sind.

Alles in der übergeordneten Vorlage wird im übergeordneten Bereich kompiliert. Alles in der untergeordneten Vorlage wird im untergeordneten Bereich kompiliert.

Weitere Informationen zum Kompilierungsbereich von Komponenten finden Sie in der Dokumentation von Vue .

Was kann ich tun?

Bisher wurde viel darüber gesprochen, Dinge im richtigen Bereich zu definieren, sodass die Korrektur nur darin besteht, die changeSettingDefinition in die MainTableKomponente zu verschieben.

Es scheint so einfach, aber hier ist, was ich empfehle.

Sie möchten wahrscheinlich, dass Ihre MainTableKomponente eine dumme / präsentative Komponente ist. ( Hier ist etwas zu lesen, wenn Sie nicht wissen, was es ist, aber ein tl; dr ist, dass die Komponente nur für das Rendern von etwas verantwortlich ist - keine Logik). Das Smart / Container-Element ist für die Logik verantwortlich. In dem in Ihrer Frage angegebenen Beispiel wäre die Stammkomponente die Smart / Container-Komponente. Mit dieser Architektur können Sie die Eltern-Kind-Kommunikationsmethoden von Vue verwenden, damit die Komponenten interagieren. Sie geben die Daten MainTableüber Requisiten weiter und senden Benutzeraktionen MainTableüber Ereignisse an das übergeordnete Element . Es könnte ungefähr so ​​aussehen:

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

Das oben Genannte sollte ausreichen, um Ihnen eine gute Vorstellung davon zu geben, was zu tun ist, und um die Lösung Ihres Problems zu starten.

Flügel
quelle
3
Ist dies derzeit der am meisten bevorzugte Ansatz? Die Dinge in Vue entwickeln sich immer weiter, also würde ich fragen
Aseem
15

Sollte jemand mit dem gleichen dummen Problem landen, das ich hatte, stellen Sie sicher, dass Ihre Komponente die Eigenschaft ' data ' richtig geschrieben hat. (zB Daten und nicht Datum )

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

<script>
export default {
  name: "MyComponent",
  data() {
    return {
      name: ""
    };
  }
</script>
tno2007
quelle
1
bro ernst, ich meine ernsthaft danke
Noni
Ich hier im Jahr 2020, schrieb ich DATE
Paaksing
6

In meinem Fall war der Grund, dass ich nur das Schließen vergessen habe

</script>

Etikett.

Dies verursachte jedoch die gleiche Fehlermeldung.

Frankfurt-Laravel
quelle
3

Es ist wahrscheinlich durch Rechtschreibfehler verursacht

Ich habe einen Tippfehler beim Schließen des Skripts erhalten

</sscript>
Lätzchen
quelle
2

Wenn jemand wie ich Probleme hat, beachten Sie, dass bei Methoden zwischen Groß- und Kleinschreibung unterschieden wird:

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

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

"Methoden" sollten "Methoden" sein

Daniel Katz
quelle
2

Es handelt sich höchstwahrscheinlich um einen Rechtschreibfehler bei reservierten vuejs-Variablen. Ich bin hierher gekommen, weil ich falsch geschrieben habe computed:und vuejs meine berechneten Eigenschaftsvariablen nicht erkennen würde. Wenn Sie also einen solchen Fehler haben, überprüfen Sie zuerst Ihre Rechtschreibung!

Mahatmanich
quelle
2

Wenn Sie eine zweimalige vue-Instanz verwenden. Dann wird es Ihnen diesen Fehler geben. Zum Beispiel in app.js und Ihrem eigenen Skript-Tag in der Ansichtsdatei. Einfach einmal verwenden

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

Ich hatte zwei methods:in der <script>, um zu zeigen, dass man stundenlang nach etwas suchen kann, das so ein einfacher Fehler war.

Lerncodes123
quelle
1

Ich habe diesen Fehler erhalten, als ich versucht habe, einer Statuseigenschaft während der Instanziierung eine Komponenteneigenschaft zuzuweisen

export default {
 props: ['value1'],
 data() {
  return {
   value2: this.value1 // throws the error
   }
  }, 
 created(){
  this.value2 = this.value1 // safe
 }
}
Ich möchte Antworten
quelle
1

Mein Problem war, dass ich die Methoden in meinem Datenobjekt platzierte. Formatieren Sie es einfach so und es wird gut funktionieren.

<script>
module.exports = {
    data: () => {
        return {
            name: ""
        }
    },
    methods: {
        myFunc() {
            // code
        }
    }
}
</script>
Pwntastic
quelle
1

In meinem Fall war es eine Eigenschaft, die mir den Fehler und die korrekte Schreibweise gab und mir trotzdem den Fehler in der Konsole gab. Ich habe so viel gesucht und nichts hat für mich funktioniert, bis ich ihm Strg + F5 und Voilá gegeben habe! Fehler wurde entfernt. : 'v

Jennifer Miranda Beuses
quelle