提取所有子数据后,vuejs父事件

时间:2018-12-29 00:33:58

标签: vue.js vue-router

我是vuejs的新手,我是否应该使用事件或vuex来了解何时从服务器中获取了所有子级数据,仍然有些困惑。

例如,我的某条路线的结构如下:

<Parent>
   <Child1 />
   <Child2 />
   <Child3 />
</Parent>

然后在每个子组件中,我都有一个fetchData()方法,该方法从不同的端点从服务器检索数据:

export default {        
    created() {
      // fetch data
        this.fetchData()    
    },
    methods: {
        fetchData() {
            this.$http.get('/api/dataN', {})
                .then(response => {
                    // do something
                }).catch(error => {})
        }
    }
}

一旦所有子数据都已获取,父母怎么知道?

我想将此功能设为通用函数,因此在另一条路线只有两个孩子(或超过3个)的情况下,总是会触发事件。

我看过父挂钩,但是据我了解,创建时已获取子数据(已加载组件),据我所知,父挂钩对我没有用。

我需要为父级修改DOM的示例: example

3 个答案:

答案 0 :(得分:1)

这是一个使用异步回调函数的示例。每个子组件都返回其自身的异步函数(例如api调用),父组件将解析该函数​​并保留一个触发回调次数的运行计数器:

Vue.component('child', {
  template: `<div>I take {{ timeout }} seconds to finish. <span>{{ message }}</span></div>`,
  props: ['callback'],
  data () {
    return {
      timeout: Math.ceil(Math.random() * 10),
      complete: false
    }
  },
  computed: {
    message () {
      return this.complete ? 'Done!' : 'Working...'
    }
  },
  mounted() {
    setTimeout(() => {
      this.complete = !this.complete
      
      const func = async () => {}
      
      this.callback.call(this, func)
    }, this.timeout * 1000)
  }
})

new Vue({
  el: '#app',
  data() {
    return {
      max: 10,
      counter: 0
    }
  },
  computed: {
    message () {
      return this.counter < this.max ? `${this.max - this.counter} Jobs remaining` : `All jobs complete!`
    }
  },
  methods: {
    async callback(func) {
      const data = await func()
      
      this.counter += 1
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
  <p>{{ message }}</p>
  <child v-for="i in max" :key="i" :callback="callback" style="margin: 1rem 0;"></child>
</div>

答案 1 :(得分:1)

最后,我做了一点不同:

  1. 孩子保持微调状态
  2. $ emit为父对象提供回调-开启微调器 /关闭

这不是我的完整代码,但为您提供了如何解决它的示例。

<div id="app">
<div id="spinner" v-show="spinner" key=1></div>
  <child v-show="!spinner" @spinnerCallback="setSpinner" />
</div>

Vue.component('child', {
  template: `<div>this is child data</div>`,

  data() {
        return {
            tiles: '',
        }
    },
    created() {
      // start spinner
      this.$emit('spinnerCallback', 1)

      //fetch data
        this.fetchData()
    },
    methods: {
        fetchData() {
            this.$http.get('/api/dashboard', {})
                .then(response => {
                    this.tiles = response.data.tiles//,
                    this.$emit('spinnerCallback', 0)
                }).catch(error => {})
        }
    }
})

var app = new Vue({
  el: '#app',
    data() {
        return {
            spinner: null,
        }
    },
    methods: {
        setSpinner: function(value) {
          // toggle spinner
          if (value == 1) {
            this.spinner = true;
          } else {
            this.spinner = false;
          }
        }
    },
})

答案 2 :(得分:0)

您应该从每个子组件中发出一个事件,父组件添加一个名为nb_components的数据属性,该数据属性使用组件数进行初始化,而另一个count则在每次子组件执行该操作时都会增加它的任务:

export default {

  created() {
    // fetch data
    this.fetchData()
  },
  methods: {
    fetchData() {
      this.$http.get('/api/dataN', {})
        .then(response => {
          this.$emit('fetch-data')
        }).catch(error => {})
    }
  }
}

和父组件:

<Parent>
  <Child1 @fetch-data="increment"  />
  <Child2 @fetch-data="increment"  />
  <Child3 @fetch-data="increment"  />
</Parent>

脚本

 data(){
       return{
         count:0,
         nb_components:3
         ....
        }
      },
  methods:{
       increment(){
          this.count++;
          if(this.count==this.nb_components){
                 //stop the spinner
             }
          }
    ...
  }