Rumah  >  Soal Jawab  >  teks badan

Bagaimana untuk mengembalikan pemerhati daripada fungsi global dalam Vue 2

<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粉682987577P粉682987577409 hari yang lalu464

membalas semua(2)saya akan balas

  • P粉788571316

    P粉7885713162023-09-06 19:21:54

    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>

    balas
    0
  • P粉063039990

    P粉0630399902023-09-06 09:50:26

    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.

    balas
    0
  • Batalbalas