Bagaimana untuk mengembalikan pemerhati daripada fungsi global dalam Vue 2
P粉682987577
P粉682987577 2023-09-05 22:03:02
0
2
527
<p>Helo, saya ada soalan: Dalam main.js, saya mempunyai fungsi global <code>getSites</code> </p><p> Fungsi ini berfungsi menggunakan async/menunggu dan mengembalikan data tapak secara tidak segerak. </p><p> Saya juga mempunyai pembolehubah global yang dipanggil <code>lockSitesLoading</code> yang saya tetapkan kepada benar apabila saya mula mendapat data daripada API, saya memerlukan pembolehubah ini untuk menghalang pelanggan daripada membuat permintaan baharu kepada pelayan. </p><p> Dalam fungsi pertama <code>getSites</code>, saya perlu menyemak pembolehubah ini <code>lockSitesLoading</code> dan jika ia benar, mula memantaunya sehingga ia berubah kepada palsu. Pada ketika ini, saya ingin memanggil <code>getSites</code> </p><p> Masalahnya bermula sekarang kerana apabila saya mula menonton pembolehubah, fungsi tidak menunggu pembolehubah menjadi palsu, tetapi mengembalikan <kod>undefined</code>. </p><p> Berikut ialah kod saya: </p> <p>Component.vue:</p> <pre class="brush:php;toolbar:false;">async mounted() { biarkan vm = ini; tapak const = menunggu vm.getSites(); vm.sites = tapak.data },</pre> <p>main.js:</p> <pre class="brush:php;toolbar:false;">async getSites() { biarkan vm = ini; if (vm.$store.state.lockSitesLoading) { vm.$watch('$store.state.lockSitesLoading', () => vm.getSites()); } lain { kembalikan vm._getSitesOnline(); //Ini adalah fungsi yang sebenarnya mendapat data daripada pelayan }</pre> <p>Saya cuba menyelesaikannya dengan cara ini tetapi ia tidak berjaya. Ada idea? </p>
P粉682987577
P粉682987577

membalas semua(2)
P粉788571316

Saya tidak tahu sama ada anda telah menyediakannyalockSitesLoading = true, dan saya tidak tahu di mana anda telah menyediakannya.

Berikut ialah contoh yang berkesan.

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    sites: [],
    lockSitesLoading: false
  },
  actions: {
    async loadSites(context) {
        context.state.lockSitesLoading = true;    
        const sites = await context.dispatch('getSites');
        context.state.sites = sites.data;
        context.state.lockSitesLoading = false;    
    },
    async getSites(context) {
        return new Promise(function(resolve, reject){
          setTimeout(function(){
            resolve({ data: ['site1', 'site2', 'site3']})              
          },1000)
        })
      }    
  }
})

new Vue(
  { 
    el:'#app',
    store: store,
    async mounted() {
       await this.$store.dispatch('loadSites')
    },
    computed: {
      sites() { return this.$store.state.sites },
      lockSitesLoading() { return this.$store.state.lockSitesLoading }
    },
    watch: {
      lockSitesLoading(newVal, oldVal) {
          console.log(`lockSitesLoading: ${oldVal} -> ${newVal}`)
      }
    }    
  }
)
#app { line-height: 1.75; }
[v-cloak] { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.14/vue.min.js"></script>
<script src="https://unpkg.com/vuex@3.6.2/dist/vuex.js"></script>
<div id="app" v-cloak>
  sites: {{sites}}<br/>
  lockSitesLoading: {{lockSitesLoading}}
</div>
P粉063039990

Pada asasnya memerlukan janji untuk menunggu:

let unwatch;

  await new Promise(resolve => {
    unwatch = vm.$watch('$store.state.lockSitesLoading', loading => {
      if (!loading) {
        resolve();
      }
    }, { immediate: true });
  });

  unwatch();

  await vm._getSitesOnline();

Sila ambil perhatian bahawa jika lockSitesLoadingmenyekat pelaksanaan atas sebab tertentu, ini akan menyebabkan kebocoran ingatan.

Mungkin terdapat cara yang lebih bersih untuk mencapai ini menggunakan komposisi API dan VueUse.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan