如何在Vue 2中全域函數中傳回一個觀察者
P粉682987577
P粉682987577 2023-09-05 22:03:02
0
2
385
<p>你好,我有一個問題:在main.js中,我有一個全域函數<code>getSites</code>,用於從API中擷取網站清單。 </p><p> 這個函數使用async/await工作,並且非同步返回網站資料。 </p><p> 我還有一個全域變數叫做<code>lockSitesLoading</code>,當我開始從API中取得資料時,我將其設為true,我需要這個變數來防止客戶端向伺服器發出新請求。 </p><p> 在第一個函數<code>getSites</code>中,我需要檢查這個變數<code>lockSitesLoading</code>,如果它是true,就開始監視它直到它變成false。在這一點上,我想遞歸呼叫<code>getSites</code>。 </p><p> 問題現在開始了,因為當我開始監視變數時,這個函數並沒有等待變數變成false,而是回傳<code>undefined</code>。 </p><p> 這裡是我的程式碼:</p> <p>組件.vue:</p> <pre class="brush:php;toolbar:false;">async mounted() { let vm = this; const sites = await vm.getSites(); vm.sites = sites.data },</pre> <p>main.js:</p> <pre class="brush:php;toolbar:false;">async getSites() { let vm = this; if (vm.$store.state.lockSitesLoading) { vm.$watch('$store.state.lockSitesLoading', () => vm.getSites()); } else { return vm._getSitesOnline(); //這是實際從伺服器取得資料的函數 }</pre> <p>我嘗試以這種方式解決,但不起作用。有什麼想法嗎? </p>
P粉682987577
P粉682987577

全部回覆(2)
P粉788571316

不清楚你是否設定了lockSitesLoading = true,也不清楚你在哪裡設定了。

這是一個可工作的範例。

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

基本上需要一個等待的承諾:

let unwatch;

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

  unwatch();

  await vm._getSitesOnline();

請注意,如果lockSitesLoading由於某種原因阻止執行,這將導致記憶體洩漏。

使用組合API和VueUse組合式可能有更簡潔的方法來實現這一點。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!