向子组件传递动态的多级数组对象,子组件内初始时获取不到深层级属性值的解决方法

一、问题产生背景:

  向子组件传一个动态生成的数组,数组中包含着多级的对象数组

// 父组件声明的数组对象
slots: any = [
        {
            flex: 1,
            values: [],
            className: 'pro_slot',
            textAlign: 'center'
        }, {
            divider: true,
            content: '-',
            className: ''
        }, {
            flex: 1,
            values: [],
            className: 'city_slot',
            textAlign: 'center'
        },
        {
            divider: true,
            content: '-',
            className: ''
        }, {
            flex: 1,
            values: [],
            className: 'aera_slot',
            textAlign: 'center'
        }
    ];
// 父组件内调用请求数据更换slots部分属性值
async initAreaData(id?: any) {
        const pro_res = await getCityData(id);
        const pro_data = pro_res.data.data;
        this.$set(this.slots[0], 'values', pro_data);
        const city_res = await getCityData(pro_data[0].region_id);
        const city_data = city_res.data.data;
        this.$set(this.slots[2], 'values', city_data);
        const area_res = await getCityData(city_data[0].region_id);
        const area_data = area_res.data.data;
        this.$set(this.slots[4], 'values', area_data);
    }
// 传值给子组件
<areapicker2 :slots='slots' ></areapicker2>
// 子组件接收
 props: {
      slots: {
         type: Array
     },
 }
// 子组件页面使用
<ul v-if='slot.values' :class="['slots',{select_slots: slot.values}]" :id="'slot' + slotIndex"  v-for="(slot, slotIndex) in slots" :key="slotIndex">
    <li v-for="(itemValue, index) in slot.values" :key="index">
        {{itemValue.region_name}}
     </li>
</ul>    
// 子组件初始化时打印传过来的slots数组对象及其属性值
mounted () {
  console.log('this.slots',this.slots)
  console.log('this.slots[0]', this.slots[0])
  console.log('this.slots[0].values', this.slots[0].values)
}

 打印结果如下:

发现页面是正常渲染的所有数据,但是在js中,获取数组对象中更深层次的数组值时,发现this.slots[0].values拿到的是原先的父组件的slots数组中默认的值,而不是有34个内容的Array。

二、尝试解决

(1)加上定时器,发现可以获取得到,取到后再执行相关逻辑代码,缺点是延迟时间不好把控,太短基本还是取不到值,太长又可能有其他问题,需要结合实际情况优化;或者使用setInterval,再获取到之后记得立马清除clearInterval定时器

mounted () {
    console.log('this.slots',this.slots)
    console.log('this.slots[0]', this.slots[0])
    setTimeout(()=>{
    console.log('this.slots[0].values',this.slots[0].values)
    console.log('this.slots[2].values',this.slots[2].values)
    console.log('this.slots[4].values',this.slots[4].values)
  },2000)
}

 打印结果如下:

(2)使用深度监听,取到值后再执行相关逻辑代码,缺点是看情况存在多次变化多次执行监听函数的情况,直到最后一次才能全部获取到正确的值,像前面通过三次异步请求改变了slots三处values属性值,监听函数触发了三次,第三次才能获取到全部的值

 // 子组件深度监听slots
watch: {
    slots: {
        handler: function (newval, oldval) {
            console.log('this.slots', this.slots)
            console.log('this.slots[0].values',this.slots[0].values)
            console.log('this.slots[2].values',this.slots[2].values)
            console.log('this.slots[4].values',this.slots[4].values)
        },
        deep: true
    }
},

打印结果如下:

(3)使用vuex来通信

原文地址:https://www.cnblogs.com/ahao68/p/11176771.html