Verwenden von $ refs in einer berechneten Eigenschaft

85

Wie greife ich auf $refsberechnete Daten zu? Es ist immer undefiniert, wenn die berechnete Eigenschaft zum ersten Mal ausgeführt wird.

Eric Guan
quelle
6
Ja, es wird nur definiert, wenn die erste Renderschleife abgeschlossen ist. Für das, was es wert ist, wird ausdrücklich nicht empfohlen, $ refs in berechneten Eigenschaften zu verwenden, da es nicht reaktiv ist. vuejs.org/v2/guide/components.html#Child-Component-Refs Möglicherweise müssen Sie ein besseres Muster finden ...
Cobaltway
Verwenden der Watch-Funktion innerhalb des Mounted: Geben Sie hier die
Linkbeschreibung

Antworten:

129

Als ich hier meine eigene Frage beantwortete, konnte ich nirgendwo anders eine zufriedenstellende Antwort finden. Manchmal benötigen Sie nur Zugriff auf ein dom-Element, um einige Berechnungen durchzuführen. Hoffentlich ist dies für andere hilfreich.

Ich musste Vue austricksen, um die berechnete Eigenschaft zu aktualisieren, sobald die Komponente gemountet war.

Vue.component('my-component', {
    data(){
        return {
            isMounted: false
        }
    },
    computed:{
        property(){
            if(!this.isMounted)
                return;
            // this.$refs is available
        }
    },
    mounted(){
        this.isMounted = true;
    }
})
Eric Guan
quelle
2
Hatte genau die gleiche Anforderung und dies war die einzige praktikable Lösung, die ich gefunden habe. Band die class -Eigenschaft an eine berechnete Eigenschaft und musste einige Klassen anwenden, wenn für eine verschachtelte Komponente (die Referenz) einige Eigenschaften festgelegt waren.
Christophe Geers
@Bondsmith Sorry haha, ich bin der Fragesteller und der Antwortende. Ich glaube, ich habe vergessen, meine eigene Antwort zu akzeptieren
Eric Guan
Ich habe es nicht bemerkt. Das ist lustig ツ
Bondsmith
Sehr hilfreich, danke @EricGuan, dass Sie sich die Zeit genommen haben, Ihre eigene Frage zu beantworten, um anderen zu helfen
timmyLtus
18

Ich denke, es ist wichtig, den Vue js-Leitfaden zu zitieren :

$ refs werden erst nach dem Rendern der Komponente ausgefüllt und sind nicht reaktiv. Es ist nur als Notluke für die direkte Manipulation von Kindern gedacht. Sie sollten vermeiden, über Vorlagen oder berechnete Eigenschaften auf $ refs zuzugreifen.

Es ist daher nichts, was Sie tun sollten, obwohl Sie sich immer darum herumhacken können.

Geoffroy
quelle
15

Wenn Sie das $refsnach einem brauchen, können v-ifSie den updated() Haken benutzen .

<div v-if="myProp"></div>


updated() {
    if (!this.myProp) return;
    /// this.$refs is available
},
Facyo Kouch
quelle
ordentlicher Trick! Integrieren Sie die v-ifBedingungen in die computedLogik des Systems, damit sie als Abhängigkeiten registriert werden. Genau die Antwort auf die Neugier eines Elements mit refund umgeschaltet vonv-if
plong0
6

Ich bin gerade mit demselben Problem gekommen und habe festgestellt, dass dies die Art von Situation ist, in der berechnete Eigenschaften nicht funktionieren.

Gemäß der aktuellen Dokumentation ( https://vuejs.org/v2/guide/computed.html ):

"[...] Anstelle einer berechneten Eigenschaft können wir dieselbe Funktion wie eine Methode definieren. Für das Endergebnis sind die beiden Ansätze tatsächlich genau gleich. Der Unterschied besteht jedoch darin, dass berechnete Eigenschaften basierend auf ihrer Reaktivität zwischengespeichert werden Abhängigkeiten. Eine berechnete Eigenschaft wird nur dann neu bewertet, wenn sich einige ihrer reaktiven Abhängigkeiten geändert haben. "

Was in diesen Situationen (wahrscheinlich) passiert, ist, dass das Beenden des gemounteten Lebenszyklus der Komponente und das Festlegen der Refs nicht als reaktive Änderung der Abhängigkeiten der berechneten Eigenschaft gilt.

In meinem Fall habe ich beispielsweise eine Schaltfläche, die deaktiviert werden muss, wenn meine Referenztabelle keine ausgewählte Zeile enthält. Dieser Code funktioniert also nicht:

<button :disabled="!anySelected">Test</button>

computed: {
    anySelected () {
      if (!this.$refs.table) return false

      return this.$refs.table.selected.length > 0
    }
}

Sie können die berechnete Eigenschaft durch eine Methode ersetzen, und das sollte ordnungsgemäß funktionieren:

<button :disabled="!anySelected()">Test</button>

methods: {
    anySelected () {
      if (!this.$refs.table) return false

      return this.$refs.table.selected.length > 0
    }
}
Bruno Soares
quelle
3
Ich denke, dieser Ansatz ist der bisher beste. Es breitet nicht die Anweisungen, um data(), updated()und andere Teile. Sauber und prägnant.
MongoLato
3

Für andere Benutzer wie mich, die nur einige Daten an prop übergeben müssen, habe ich datastattdessen verwendetcomputed

Vue.component('my-component', {
    data(){
        return {
            myProp: null
        }
    },    
    mounted(){
        this.myProp= 'hello'    
        //$refs is available              
        // this.myProp is reactive, bind will work to property
    }
})
Rodrigo Rodrigues
quelle
1

Verwenden Sie die Eigenschaftsbindung, wenn Sie möchten. : deaktivierte Stütze ist in diesem Fall reaktiv

<button :disabled="$refs.email ? $refs.email.$v.$invalid : true">Login</button>

Aber um zwei Felder zu überprüfen, habe ich keinen anderen Weg als Dummy-Methode gefunden:

<button
    :disabled="$refs.password ? checkIsValid($refs.email.$v.$invalid, $refs.password.$v.$invalid) : true">
            {{data.submitButton.value}}
</button>

methods: {
   checkIsValid(email, password) {
      return email || password;
   }
}
Überdosiert
quelle