vue组件内部props,两个相关异步数据,如何确保计算出结果?

一、组件介绍(怎么确保得到a3)

1、组件内有a1,a2,用来接收父组件的传值,需要通过a1,a2来得到一个 a3
2、父组件在使用时a1,a2的来源是通过两个不同的api获取的,a1,a2都是异步的

<script>
  export default {
    name: 'Test',
    props: {
      a1: { // 异步数据
        type: Array,
        default: () => []
      },
      a2: { // 异步数据
        type: Array,
        default: () => []
      }
    },
    data() {
      return {
        a3: []
      }
    },
    watch: {
      a1: {
        deep: true,
        handler() {
          if (this.a1 && this.a2) {
            this.initA3()
          }
        }
      },
      a2: {
        deep: true,
        handler() {
          if (this.a1 && this.a2) {
            this.initA3()
          }
        }
      }
    },
    methods: {
      initA3() {
        // 对 a1、a2 进行运算后得到 a3,这里都是简化场景
        a3 = a1 + a2
      }
    }
  }
</script>

二、解决方案(目前的方案)

1、前提条件如下:(1)它是组件,尽量是不去要求父组件去控制api请求顺序,比如async await控制两个请求的顺序(2)a1,a2的来源是可能随时变的,可能通过一个按钮切换这样,不限制父组件的使用
2、目前想的 watch 是对 a1,a2进行监听,然后发生变化时,得到 a3
3、计算属性computed行不通,不能深度监听,因为这个a3是一个副作用了

三、大佬们,想请问下有其他的方案思路,谢谢

阅读 804
3 个回答
<script>
  export default {
    name: 'Test',
    props: {
      a1: { // 异步数据
        type: Array,
        default: () => []
      },
      a2: { // 异步数据
        type: Array,
        default: () => []
      }
    },
    data() {
      return {
        a3: []
      }
    },
    watch: {
      a1: {
        deep: true,
        handler(newValue, oldValue) {
          if (newValue!==oldValue) {
            this.initA3()
          }
        }
      },
      a2: {
        deep: true,
        handler(newValue, oldValue) {
          if (newValue!==oldValue) {
            this.initA3()
          }
        }
      }
    },
mounted() {
  // watch里 不建议使用immediate: true
  this.$nextTick(() => {
      this.initA3()
    })
  },
    methods: {
      initA3() {
            if (this.a1 && this.a2) {
                  // 对 a1、a2 进行运算后得到 a3,这里都是简化场景
                  a3 = a1 + a2
            } else {
console.log('看那个没有获取到')
}
      }
    }
  }
</script>

你可以用computed组合出一个对象,然后watch那个新的对象,避免重复触发

computed:{
    tempA3(){
        const {a1,a2} = this
        retutn {a1,a2}
    }
},
watch:{
    tempA3:{
        handler(val){
            const {a1,a2} = val
            if(a1 && a2){
                this.initA3()
            }
        },
        deep: true
    }
}

你要理解 MVVM 的设计逻辑。

  1. 传统软件模式中,如果我们要把一个数据显示在视图上,我们通常需要手动控制这个数据的渲染,并且在数据变化时,手动修改渲染出的视图。
  2. 于是我们就要确定数据变化的时机,及时计算、及时修改视图。这个过程往往很费力,会给我们带来茫茫多的代码复杂度。
  3. 而 MVVM 则不然,这种模式会提供数据与视图之间的映射关系,于是我们就可以只操作数据,而不太需要关注数据变化。
  4. 回到你的问题,使用 Vue 之后,我们不需要关注数据是什么时候变化的,只需要利用 computed 得到新的数据,渲染的过程是自动的。
推荐问题
宣传栏