Nur eine kurze Frage.

Können Sie Vue.js zwingen, alles neu zu laden / neu zu berechnen ? Wenn das so ist, wie?

312
Dave 20 Aug. 2015 im 00:43

16 Antworten

Beste Antwort

Versuchen Sie diesen Zauber:

vm.$forceUpdate();

Keine Notwendigkeit, hängende Vars zu erstellen :)

Update: Ich habe diese Lösung gefunden, als ich erst mit VueJS angefangen habe. Weitere Untersuchungen haben diesen Ansatz jedoch als Krücke bewiesen. Soweit ich mich erinnere, habe ich es nach einer Weile losgeworden, indem ich einfach alle Eigenschaften, die nicht automatisch aktualisiert wurden (meistens verschachtelte), in berechnete Eigenschaften eingefügt habe.

Weitere Informationen finden Sie hier: https://vuejs.org/v2/guide/computed.html

221
Boris Mossounov 10 Feb. 2017 im 14:33

Ich habe einen Weg gefunden. Es ist ein bisschen hacky, funktioniert aber.

vm.$set("x",0);
vm.$delete("x");

Dabei ist vm Ihr Ansichtsmodellobjekt und x eine nicht vorhandene Variable.

Vue.js beschwert sich darüber im Konsolenprotokoll, löst jedoch eine Aktualisierung aller Daten aus. Getestet mit Version 1.0.26.

2
Laszlo the Wiz 3 Sept. 2016 im 22:11

Ich hatte dieses Problem mit einer Bildergalerie, die ich aufgrund von Änderungen, die auf einer anderen Registerkarte vorgenommen wurden, erneut rendern wollte. Also tab1 = imageGallery, tab2 = FavoriteImages

Tab @ change = "updateGallery ()" -> Dies zwingt meine v-for-Direktive, die Funktion filteredImages bei jedem Tabwechsel zu verarbeiten.

<script>
export default {
  data() {
    return {
      currentTab: 0,
      tab: null,
      colorFilter: "",
      colors: ["None", "Beige", "Black"], 
      items: ["Image Gallery", "Favorite Images"]
    };
  },
  methods: {
    filteredImages: function() {
      return this.$store.getters.getImageDatabase.filter(img => {
        if (img.color.match(this.colorFilter)) return true;
      });
    },
    updateGallery: async function() {
      // instance is responsive to changes
      // change is made and forces filteredImages to do its thing
      // async await forces the browser to slow down and allows changes to take effect
      await this.$nextTick(function() {
        this.colorFilter = "Black";
      });

      await this.$nextTick(function() {
        // Doesnt hurt to zero out filters on change
        this.colorFilter = "";
      });
    }
  }
};
</script>
0
Jason 31 Aug. 2019 im 03:25

Dies scheint eine ziemlich saubere Lösung von matthiasg auf dieses Problem:

Sie können auch :key="someVariableUnderYourControl" verwenden und den Schlüssel ändern, wenn die Komponente vollständig neu erstellt werden soll

Für meinen Anwendungsfall habe ich einen Vuex-Getter als Requisite in eine Komponente eingespeist. Irgendwie würde Vuex die Daten abrufen, aber die Reaktivität würde nicht zuverlässig eintreten, um die Komponente neu zu rendern. In meinem Fall garantierte das Setzen der Komponente key auf ein Attribut auf der Requisite eine Aktualisierung, wenn die Getter (und das Attribut) endgültig aufgelöst wurden.

77
Brian Kung 12 Feb. 2018 im 20:44

Bitte lesen Sie dies http://michaelnthiessen.com/force-re-render/

Der schreckliche Weg: die gesamte Seite neu laden
Der schreckliche Weg: mit dem v-if-Hack
Der bessere Weg: Verwenden der integrierten ForceUpdate-Methode von Vue
Der beste Weg: Schlüsselwechsel für Ihre Komponente

<template>
   <component-to-re-render :key="componentKey" />
</template>

<script>
 export default {
  data() {
    return {
      componentKey: 0,
    };
  },
  methods: {
    forceRerender() {
      this.componentKey += 1;  
    }
  }
 }
</script>

Ich benutze auch Uhr: in einigen Situationen.

25
Yash 25 Jän. 2019 im 14:42

Sicher .. Sie können einfach das Schlüsselattribut verwenden, um jederzeit ein erneutes Rendern (Neuerstellen) zu erzwingen.

<mycomponent :key="somevalueunderyourcontrol"></mycomponent>

Ein Beispiel finden Sie unter https://jsfiddle.net/mgoetzke/epqy1xgf/

Es wurde auch hier besprochen: https://github.com/vuejs/Discussion/issues / 356 # issuecomment-336060875

14
mgoetzke 18 Aug. 2018 im 14:34

: key = "$ route.params.param1" Verwenden Sie einfach den Schlüssel mit Ihren Parametern, um die untergeordneten Elemente automatisch neu zu laden.

0
Rai Ahmad Fraz 22 Apr. 2019 im 13:04
<my-component :key="uniqueKey" />

Zusammen mit this.$set(obj,'obj_key',value) verwenden und aktualisiere uniqueKey für jede Aktualisierung des Objektwerts (obj) für jedes Update this.uniqueKey++

Es hat bei mir so funktioniert

11
Pushkar Shirodkar 19 Nov. 2019 im 06:08

Warum?

... müssen Sie ein Update erzwingen?

Vielleicht erkunden Sie Vue nicht von seiner besten Seite:

Damit Vue automatisch auf Wertänderungen reagiert, müssen die Objekte zunächst in data deklariert werden. Wenn nicht, müssen sie mit Vue.set() hinzugefügt werden.

Siehe Kommentare in der Demo unten. Oder öffnen Sie die gleiche Demo in einer JSFiddle hier.

new Vue({
  el: '#app',
  data: {
    person: {
      name: 'Edson'
    }
  },
  methods: {
    changeName() {
      // because name is declared in data, whenever it
      // changes, Vue automatically updates
      this.person.name = 'Arantes';
    },
    changeNickname() {
      // because nickname is NOT declared in data, when it
      // changes, Vue will NOT automatically update
      this.person.nickname = 'Pele';
      // although if anything else updates, this change will be seen
    },
    changeNicknameProperly() {
      // when some property is NOT INITIALLY declared in data, the correct way
      // to add it is using Vue.set or this.$set
      Vue.set(this.person, 'address', '123th avenue.');
      
      // subsequent changes can be done directly now and it will auto update
      this.person.address = '345th avenue.';
    }
  }
})
/* CSS just for the demo, it is not necessary at all! */
span:nth-of-type(1),button:nth-of-type(1) { color: blue; }
span:nth-of-type(2),button:nth-of-type(2) { color: red; }
span:nth-of-type(3),button:nth-of-type(3) { color: green; }
span { font-family: monospace }
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <span>person.name: {{ person.name }}</span><br>
  <span>person.nickname: {{ person.nickname }}</span><br>
  <span>person.address: {{ person.address }}</span><br>
  <br>
  <button @click="changeName">this.person.name = 'Arantes'; (will auto update because `name` was in `data`)</button><br>
  <button @click="changeNickname">this.person.nickname = 'Pele'; (will NOT auto update because `nickname` was not in `data`)</button><br>
  <button @click="changeNicknameProperly">Vue.set(this.person, 'address', '99th st.'); (WILL auto update even though `address` was not in `data`)</button>
  <br>
  <br>
  For more info, read the comments in the code. Or check the docs on <b>Reactivity</b> (link below).
</div>

Um diesen Teil von Vue zu beherrschen, überprüfen Sie die offiziellen Dokumente zu Reaktivität - Änderungserkennungsvorbehalte. Es ist ein Muss zu lesen!

43
acdcjunior 28 Apr. 2018 im 14:30

Das hat bei mir funktioniert.

created() {
            EventBus.$on('refresh-stores-list', () => {
                this.$forceUpdate();
            });
        },

Die andere Komponente löst das Update-Stores-List-Ereignis aus, wodurch die aktuelle Komponente erneut gerendert wird

2
Eric Aya 22 Feb. 2019 im 08:47

Verwenden Sie vm.$set('varName', value). Weitere Informationen finden Sie unter Change_Detection_Caveats.

23
denis.peplin 3 Juli 2016 im 18:41

Sie können dies also auf zwei Arten tun:

1). Sie können $forceUpdate() in Ihrem Methodenhandler verwenden, d.h.

<your-component @click="reRender()"></your-component>

<script>
export default {
   methods: {
     reRender(){
        this.$forceUpdate()
     }
   }
}
</script>

2). Sie können Ihrer Komponente ein :key -Attribut zuweisen und beim erneuten Rendern erhöhen

<your-component :key="index" @click="reRender()"></your-component>

<script>
export default {
   data() {
     return {
        index: 1
     }
   },
   methods: {
     reRender(){
        this.index++
     }
   }
}
</script>
5
Shahrukh Anwar 17 Feb. 2020 im 05:27

Hat für mich gearbeitet

    data () {
        return {
            userInfo: null,
            offers: null
        }
    },

    watch: {
        '$route'() {
            this.userInfo = null
            this.offers = null
            this.loadUserInfo()
            this.getUserOffers()
        }
    }
1
tuwilof 20 Juni 2019 im 21:33

Mit der v-if-Direktive

<div v-if="trulyvalue">
    <component-here />
 </div>

Wenn Sie also einfach den Wert von truevalue von false auf true ändern, wird die Komponente zwischen div erneut erneut gerendert

4
Geoff 8 März 2018 im 20:56

Stoppen Sie die langen Codierungen, um die Komponente neu zu laden / neu zu rendern / zu aktualisieren. Dafür gibt es eine Vue.JS-Methode.

Verwenden Sie einfach das Attribut :key.

Beispielsweise:

<my-component :key="unique" />

Ich benutze diesen im BS Vue Table Slot. Ich sage, dass ich etwas für diese Komponente tun werde, also mache sie einzigartig.

5
IlGala 27 Sept. 2019 im 10:29

Versuchen Sie, die aktuelle Seite mit this.$router.go(0); manuell neu zu laden.

18
Poy Chang 8 Juni 2018 im 09:06