坑:vue2在props时仅接受第一次返回数据的解决办法

发布时间 2023-07-31 13:51:04作者: 致爱丽丝

今天在做项目时遇到了一个bug,在列表页进入详情页时带入list以便子组件遍历使用,使用props传参,该list在父组件由created生命周期函数访问接口获取,然后子组件在使用时,直接使用props接收并调用,大概代码如下:

// 父组件

<Child :list='list' />

...
created(){
getListApi().then(list=>{
  this.list = list
})
}

//

...
props:{
list:{
type:Array,
default:()=>[]
}
},

methods:{
loadList(){
// 遍历list以获取对应的name
}
}

遇到了一个问题:当返回到上一页也就是列表页的时候,子组件的的值渲染值并不是遍历得到的那个值,而是它的初值,但假如我手速够快返回的就正常了
经过一番扪心自问+关爱后得到了答案:

  1. 父组件的created在生命周期里只会执行一遍,但当我从下一页回退回来的时候,整个生命周期会被重新执行,这一点没有问题,问题在于使用props的传参方式
    props的方式传递给子组件,子组件只会接收一次,也就是说,假设第一次传递给子组件的是一个有长度的list是经过异步请求后的结果,那如果在未来得及请求接口的情况下(也就是手速够快),传递给子组件的就是[],而子组件的props仅接收来自父组件的第一次数据,因而导致了上面的bug
    过程不必多说(委屈屈就对了),接下来看解决方案:

方案1:
基于props方式仅接收第一次传递数据的方式,可以使用watch + data结合的方式,即使用props接收数据值记作1,data重新定义这个数据值记作2,watch在接听props1时重新将变化的值赋给data中的2,如此就可以解决这个问题

// 子组件

props:{
list:{
type:Array,
default:()=>[]
}
},
watch:{
list(n){
console.log(n)
console.log(this.myList) // 对比一下会发现,这是不一样的!!!我真的好气啊啊啊
this.myList = n  // 关键代码 将变化后的值重新赋给myList ,具体业务场景下,也可以判断如果有值再加 
}
},
data(){
return {
  myList:this.list
  }
}

方案2:
可以在父组件获取到数据时就将数据存入到vuex中,这样子组件在使用时就可以直接获取到list,不必再考虑还会有初始值的问题,至于vuex的刷新会失效问题,只需要寻找一款对应的vuex插件就可以解决。

以上。