关于使用 uni-app 开发小程序时,出现的父子组件传值时,Object 类型的 props,内存地址不同的问题

太坑了家人扪,谁能想到,在 H5 正常运行的父子组件 props 传值,会在小程序出现问题啊!

这周,咱上头让俺把原本基于 H5 开发的网站,改成小程序,还好这也不是第一次了,咱经验丰富,项目开始就用 uni-app 开发。

在修改了一些 H5 和小程序的差异后,进到了一个只有树状结构的页面里,对没错就是 无限级树形控件tree,不过咱把它小小改动一下来适应设计稿。这个树形控件的数据,除了顶级节点,其他都是在点击下拉后,请求接口动态渲染的。俺轻轻点了下下拉,发现,只有箭头变了变,但是没有出现应有的数据。

调试了半天,抓了半手头发后,咱比较了父组件的原始数组和子组件的 props 接收的数组的内存地址,发现,他!们!不!一!样!但是,在 H5 环境下,他们是一样的!直接给俺整无语了。

想了半天,想到一个之前用过的,感觉不怎么规范的写法,就是在子组件不使用 props 接收父组件的属性,而是使用函数,参数就是需要修改的对象或数组。下面是个例子:

// 父组件.vue
<template>
<child ref="childref" />
</template>

<script>
import child from './child.vue'
export default {
  components: {
    child,
  },
  data() {
    return {
      list:[{foo:1}]
    }
  },
  mounted() {
    this.$refs.childref.changeArray(this.list);
  }
}
</script>

// child.vue
<script>
export default {
  data() {
    return {
      childList:[]
    }
  },
  methods: {
    changeArray(list) {
      this.childList = list
    }  
  }
}
</script>

这个例子比较简单,咱碰到的更加复杂,因为,子组件里面还有孙组件!孙组件还有自引用,而且他们,都会使用 Object 类型的数据,那现在该怎么办呢?当然是 watch 监听数据变化啦,下面是一个示例代码:

  watch: {
    items() {
      for (let i = 0; i < this.items.length; i++) {
        const item = this.items[i];
        this.$nextTick(() => {
          this.$refs.treeNode[i].changeItem(item);
        });
      }
    },
  },

只需要循环的调用子组件的修改函数就可以啦,至于为什么要用 nextTick,当然是不异步的话,数据刚修改完,组件还没渲染,refs 还没有数据啦。那为什么要 refs 后面会带 [i] 呢?因为咱在 v-for 中使用了 ref。这样,就完美解决了在小程序环境下,父子组件 Object 内存地址不一致的问题啦。

这个方法只是抛砖引玉,如果有人有更好的方法的话,希望可以评论或者私聊!

posted @ 2022-10-26 15:59  FreezeNow  阅读(830)  评论(0编辑  收藏  举报