So geben Sie einen Beobachter von einer globalen Funktion in Vue 2 zurück
P粉682987577
P粉682987577 2023-09-05 22:03:02
0
2
493
<p>Hallo, ich habe eine Frage: In main.js habe ich eine globale Funktion <code>getSites</code>, die die Liste der Websites von der API abruft. </p><p> Diese Funktion verwendet async/await und gibt Site-Daten asynchron zurück. </p><p> Ich habe auch eine globale Variable namens <code>lockSitesLoading</code>, die ich auf true setze, wenn ich anfange, Daten von der API abzurufen. Ich benötige diese Variable, um zu verhindern, dass der Client neue Anfragen an den Server stellt. </p><p> In der ersten Funktion <code>getSites</code> muss ich diese Variable <code>lockSitesLoading</code> überprüfen und, wenn sie wahr ist, mit der Überwachung beginnen, bis sie sich in falsch ändert. An dieser Stelle möchte ich <code>getSites</code> rekursiv aufrufen. </p><p> Das Problem beginnt jetzt, denn wenn ich anfange, die Variable zu beobachten, wartet die Funktion nicht darauf, dass die Variable falsch wird, sondern gibt <code>undefiniert</code> zurück. </p><p> Hier ist mein Code: </p> <p>Component.vue:</p> <pre class="brush:php;toolbar:false;">async mount() { let vm = this; const sites = waiting 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()); } anders { return vm._getSitesOnline(); //Dies ist die Funktion, die tatsächlich die Daten vom Server erhält }</pre> <p>Ich habe versucht, es auf diese Weise zu lösen, aber es funktioniert nicht. Irgendwelche Ideen? </p>
P粉682987577
P粉682987577

Antworte allen(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组合式可能有更简洁的方法来实现这一点。

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage