Vue.js dosyasını yeniden yüklemeye / yeniden oluşturmaya zorlayabilir misiniz?


234

Kısa bir soru.

Eğer zorlayabilir Vue.jsiçin yeniden / yeniden hesaplamak her şey? Öyleyse nasıl?


Burada daha iyi destek alabilir github.com/vuejs/Discussion/issues
Cory Danielson

Harika, o tartışma yerini bilmiyordum. Orada deneyeceğim.
Dave

Bir cevap aldın mı? Ben de bilmek istiyorum.
Oddman

Tam olarak hatırlamıyorum. Ama işte bazı ipuçlarıyla açtığım sorun: github.com/vuejs/Discussion/issues/356
Dave

Görünümde v-for yönergesi var ve ben el ile bu dizi iki nesne takas durumda kullanmalısınız. Vue bundan sonra şablonu otomatik olarak yeniden oluşturmaz. Geçici çözüm kullandım: sadece bu dizi ile herhangi bir eylem yapın (boş nesneyi itin ve sonra ekleme yapın) - bu yeniden tetikler. Ama bu özel bir durum.
Fyodor Khruschov

Yanıtlar:


239

Bu büyüyü deneyin:

vm.$forceUpdate();

Asılı vars oluşturmaya gerek yok :)

Güncelleme: Bu çözümü yalnızca VueJS ile çalışmaya başladığımda buldum. Bununla birlikte, daha fazla araştırma bu yaklaşımın koltuk değneği olduğunu kanıtladı. Hatırladığım kadarıyla, bir süre sonra basitçe (çoğunlukla iç içe olanlar) otomatik olarak yenilenemeyen tüm özellikleri hesaplanan özelliklere koyarak ondan kurtuldum.

Daha fazla bilgi burada: https://vuejs.org/v2/guide/computed.html


4
Vue'da bir form sihirbazı bileşeniyle kullanırken bu gerçekten bana yardımcı oldu. Veri değişkenleri sağlam olmasına rağmen form alanlarım alanları durum kaybediyordu. Şimdi geri döndüğümde görünümleri yenilemek için bunu kullanıyorum, setTimeout işlevine yerleştirmek zorunda kaldım.
Jimmy Ilenloa

26
Vue dosyalarında 'this. $ ForceUpdate ();'
Katinka Hesselink

1
Bu, uzun bir aksiyos çağrısından sonra güncellemek için harika çalışır.
AlfredBr

4
Kesinlikle garip bir şekilde $forceUpdate()hiç 2.5.17 üzerinde benim için çalıştı.
Abana Clara

2
@AbanaClara $ forceUpdate () asla genel bir yöntem değildi, ben Vue kaynak kodunu kazma bulundu. Ve kullanımı asla Vue'ing'in doğru yolu olmadığı için, belki de çıkarılabilir. Artık ön uç yapmadım çünkü hala orada olup olmadığını kesin olarak söyleyemem.
Boris Mossounov

82

Bu bir oldukça temiz bir çözüm gibi görünüyor matthiasg üzerine bu konuda :

:key="someVariableUnderYourControl"Bileşenin tamamen yeniden oluşturulmasını istediğinizde de anahtarı kullanabilir ve değiştirebilirsiniz

Kullanım durumum için, bir Vuex alıcısını bir bileşen olarak pervane olarak besliyordum. Bir şekilde Vuex verileri getirecekti, ancak reaktivite bileşeni yeniden oluşturmak için güvenilir bir şekilde devreye girmeyecekti. Benim durumumda, bileşen keyprop'taki bazı özniteliklere ayarlandığında, alıcılar (ve öznitelik) nihayet çözüldüğünde yenileme yenilendi.


1
Bu temiz küçük bir hile, temelde bileşenin yeniden başlatılmasını zorlar ( mountedçalıştırılacak, vb.)
BTK

1
@btk Kabul ediyorum, muhtemelen bir şeyler yapmanın "doğru" yolu değil, ama ne olduğu için oldukça temiz bir hack.
Brian Kung

1
bu yararlı. Rota değiştiğinde aynı bileşeni yeniden oluşturmak için rota tam yolunu kullanıyorum. : key = "$ route.fullPath"
Nirav Gandhi

44

Neden?

... bir güncellemeyi zorlamanız mı gerekiyor ?

Belki de Vue'yu en iyi şekilde araştırmıyorsunuz:

Vue'nun değer değişikliklerine otomatik olarak tepki vermesi için, nesnelerin başlangıçta bildirilmesidata gerekir . Veya değilse, kullanılarak eklenmelidirVue.set() .

Aşağıdaki demoda yorumlara bakın. Veya açmak bir aynı demo JSFiddle burada .

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>

Vue'nun bu bölümünde ustalaşmak için , Tepkime - Değişiklik Algılama Uyarılarını Resmi Dokümanlarına bakın . Bu bir zorunluluktur okumak!


2
Kesinlikle bu yenileme gereksinimini sorgulamanız gerektiğini kabul edin, ancak bazen görünüm yeniden değiştiğinden ve farklı varlıkları göstermeniz gerektiğinden (örnek olarak) yeniden oluşturmak için kullanıcı arayüzüne ihtiyacınız vardır. Veriler gerçekte değişmemiş olabilir.
the_dude_abides

1
Neden yeniden yüklemeniz gerekiyor? Bazı durumlarda, tarayıcı tarafından önbelleğe alınan kaynak dosyalarının (stil sayfaları / js) belirli bir süre sonra yeniden yüklenmesi gerekir. 7 gün sonra yeniden yüklenmesi gereken bir stil sayfası vardı ve bir kullanıcı sayfa erişimiyle bir sekmeyi açık tutup bu sayfada gezinmek için 7 gün sonra geri döndüyse, css 7 günden daha eskiydi.
Aurovrata

@AchielVolckaert muhtemelen cevabı zaten buldunuz, ancak evet, Vue.set()bileşenlerin içinde de çalışıyor.
acdcjunior

1
@the_dude_abides ve @ Aurovrata, bunlar ferahlatıcılığın meşru kullanımlarıdır. Poz verdiğim soru, insanların ferahlatıcıları yanlış nedenlerle nadiren yapmamasıdır.
acdcjunior

1
Belki de sadece vue'yu sadece bir oluşturma aracı olarak kullanan kötü tasarlanmış bir web uygulamasındaki bir hatayı düzeltmeye çalışıyorsunuz ve örneğin vue'nun istemci tarafı uygulama özelliklerini yok sayarak, tüm uygulamayı sunucuya gittiğinde yeniden yüklüyorsunuz. Gerçek dünyada, bulduğunuz her iğrençliği düzeltmek için her zaman zamanınız olmaz.
Warren Dew

31

Lütfen bu http://michaelnthiessen.com/force-re-render/ adresini okuyun.

Korkunç yol: tüm sayfayı yeniden yükleme
Korkunç yol: v-if hack'i kullanmak
Daha iyi yol: Vue'nun yerleşik forceUpdate yöntemini kullanmak
En iyi yol: bileşeninizde anahtar değiştirme

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

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

Ben de saat kullanıyorum: bazı durumlarda.


Kesinlikle, sana katılıyorum!
Diamond

Neredeyse Vue'dan vazgeçtim. Ancak bu sayede Vue'ya olan inancım geri yüklendi.
jokab

Bağlantı aslında korkunç bir şekilde nasıl yapılacağını göstermiyor, bu da benim app korkunç yolda gezinmek için tasarlandığından ne yazık ki ihtiyacım olan şey. Geçerli sayfaya basit bir URL, en azından uğraştığım uygulamada çalışmıyor gibi görünüyor, bu yüzden gerçekten korkunç bir şekilde nasıl yapılacağı konusunda talimatlara ihtiyacım var.
Warren Dew

@WarrenDew Lütfen takip edin: stackoverflow.com/questions/3715047/…
Yash

25

this.$router.go(0);Geçerli sayfayı manuel olarak yeniden yüklemek için kullanmayı deneyin .


3
Daha basit: bu. $ Router.go ()
Marius

Aslında @MariusAndreiana - .go () işlevi 1 isteğe bağlı olmayan parametre gerektirir
a_lovelace



12
<my-component :key="uniqueKey" />

Bununla birlikte her güncelleme için nesne (obj) değerindeki her this.$set(obj,'obj_key',value) güncelleme uniqueKeyiçin kullanım ve güncellemethis.uniqueKey++

benim için bu şekilde çalıştı


6

Yani bunu yapmanın iki yolu var,

1). $forceUpdate()Yöntem işleyicinizin içinde kullanabilirsiniz .

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

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

2). Yeniden :keygöndermek istediğinizde bileşeninize ve geliştirmenize bir özellik verebilirsiniz

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

<script>
export default {
   data() {
     return {
        index: 1
     }
   },
   methods: {
     reRender(){
        this.index++
     }
   }
}
</script>

5

v-if yönergesini kullanma

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

Bu nedenle, gerçek değer değerini false değerinden true değerine değiştirmek, div arasındaki bileşenin yeniden yeniden oluşturulmasına neden olur.


1
Bence bu, bileşeni yeniden yüklemenin en temiz yoludur. Created () yöntemine rağmen bazı başlatma öğeleri ekleyebilirsiniz.
Piotr Żak

5

Bileşeni yeniden yüklemek / yeniden oluşturmak / yenilemek için uzun kodlamaları durdurun. Bunu yapmanın bir Vue.JS yolu var.

Sadece :keyniteliği kullanın .

Örneğin:

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

Ben BS Vue Tablo Yuvası kullanıyorum. Bu bileşen için bir şeyler yapacağımı söylemek bu yüzden onu benzersiz yap.


3

Bu benim için çalıştı.

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

Diğer bileşen, refresh-store-list olayını tetikler, geçerli bileşenin yeniden oluşturulmasına neden olur


2

Bir yol buldum. Biraz kibirli ama işe yarıyor.

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

vmGörünüm modeli nesneniz nerede ve xvar olmayan bir değişken.

Vue.js, konsol günlüğünde bundan şikayet edecek, ancak tüm veriler için bir yenileme tetikliyor. 1.0.26 sürümü ile test edilmiştir.


2

Benim için çalıştı

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

    watch: {
        '$route'() {
            this.userInfo = null
            this.offers = null
            this.loadUserInfo()
            this.getUserOffers()
        }
    }


0

: key = "$ route.params.param1" sadece herhangi bir parametrenizle anahtarını kullanın, otomatik yeniden yükleme çocukları ..


4
çözümünüz hakkında ayrıntılı bilgi vermeye çalışın. kodunuzu ekleyin, anahtar kelimeleri vurgulayın
Agilanbu

0

Farklı bir sekmede yapılan değişiklikler nedeniyle yeniden oluşturmak istediğim bir resim galerisinde bu sorunu yaşadım. Yani tab1 = imageGallery, tab2 = favouriteImages

tab @ change = "updateGallery ()" -> sekmelerimi her değiştirdiğimde v-for yönergesimi filterImagesImages işlevini işlemeye zorlar.

<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

üzgünüm çocuklar, sayfa yeniden yükleme yöntemi (titrek) hariç, hiçbiri benim için çalışmıyor (: anahtar işe yaramadı).

ve benim için çalışan eski vue.js forumundan bu yöntemi buldum:

https://github.com/vuejs/Discussion/issues/356

<template>
    <div v-if="show">
       <button @click="rerender">re-render</button>
    </div>
</template>
<script>
    export default {
        data(){
            return {show:true}
        },
        methods:{
            rerender(){
                this.show = false
                this.$nextTick(() => {
                    this.show = true
                    console.log('re-render start')
                    this.$nextTick(() => {
                        console.log('re-render end')
                    })
                })
            }
        }
    }
</script>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.