Vue

异步$emit的方式

子组件调用父组件异步方法, 父组件执行后, 子组件执行剩余的部分

Posted by luoruiqing on May 12, 2020

使用场景, 子组件$emit父组件异步方法, 父组件执行后, 子组件执行剩余的部分, 用起来大概像是这样

下列例子均以 父组件方法 - fetchData 子组件方法 - fetch 对应展示例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 子组件 -->
<script>
  {
    async fetch() {
      this.loading = true
      await this.$emit('fetchData') // 异步父组件
      this.loading = false // 父组件完成后, 子组件剩余的事情
    }
  }
</script>
<!-- 父组件 -->
<script>
  {
    async fetchData() {
      this.data = await (axios.get('/')).data // 获取数据
    }
  }
</script>

解决方式

目前来说有以下几种方式可以实现.

  1. $emit方式, 传入成功和失败的回调
  2. props传入异步function对象
  3. vuex的方式

一. $emit方式

因为官方不支持emit返回值的方式, 所以最简单的是通过传入回调执行

传入成功和失败的回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- 子组件 -->
<script>
  {
    fetch() { // 这个方法也可以是async/await方法
      this.loading = true // 执行前
      this.$emit('fetchData', () => this.loading = false, console.error) // 完成后和失败的回调
    }
  }
</script>
<!-- 父组件 -->
<script>
  {
    async fetchData(resolve, reject) {
      try {
        this.data = await (axios.get('/')).data // 获取数据
        resolve() // 执行成功
      } catch (e) {
        reject(e) // 执行失败
      }
    }
  }
</script>

二. props方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!-- 子组件 -->
<script>
  {
    props: {
      fetchData: {
        type: Function,
        default() {
          return new Promise((resolve, reject) => {
            try { resolve() } catch (e) { reject() }
          })
        }
      }
    },
    methods: {
      async fetch() {
        this.loading = true // 执行前
        const data = await fetchData() // 直接父组件函数
        this.loading = false
      }
    }
  }
</script>
<!-- 父组件 -->
<script>
  {
    async fetchData() {
      const data = await (axios.get('/')).data // 获取数据
      return data
    }
  }
</script>

三. Vuex的方式

这种方式使用dispatch即可, 这里不做赘述, 请自行了解