vue prop改变,子组件更新和重新渲染

93 阅读2分钟

1 场景

父组件传递参数(假设为字符串)给子组件,子组件通过props接收

场景1 子组件利用插值{{}}在template中绑定父组件传递过来的参数

场景2 子组件在mounted生命周期函数中,利用接收到参数请求后端接口,template中绑定接口返回的数据

2 现象

对于场景1,当在父组件中,改变传递给子组件的参数,子组件的props会跟着改变,所以子组件会更新 对于场景2,当在父组件中,改变传递给子组件的参数,子组件的props会跟着改变,但是mounted生命周期函数不会再次调用,所以不会发送请求,子组件显示的依然是老数据

重新渲染,意味着组件的生命周期重新开始(beforeCreate,created,beforeMount,mounted)

更新,意味着部分生命周期函数会调用(beforeUpdate,updated)

3 分析

vue内部对与父子组件传参进行了优化,props变化时不会重新渲染子组件,但是会更新子组件,也就是说会调用beforeUpdate和updated两个生命周期函数,但是不会调用beforeCreate,created,beforeMount,mounted生命周期函数

如果是场景一,则vue本身的机制即可满足需求

如果是场景二,要根据情况决定使用哪种方法

4 场景二常规解决办法

  1. 如果子组件中的数据仅仅是请求接口返回的数据,可以选择重新渲染子组件

    1.1 给子组件加key,key变化时子组件会重新渲染

    1.2 给子组件加v-if,绑定的值在true,false中方切换时子组件会重新渲染

  2. 如果子组件中的数据只有部分是请求接口返回的数据,可以选择重新渲染子组件,也可以更新子组件中部分数据

    2.1 给子组件加ref,父组件通过ref调用子组件中的请求后端数据的方法

    2.2 在子组件中加watch(vue3中也可以用watchEffect),监听props,并调用接口

注意:接口返回的数据在template中绑定时,不要企图在beforeUpdate,updated生命周期函数中再次调用接口,以便进行子组件更新,如果这样做浏览器可能会进入死循环(因为返回的数据会触发响应式,导致vue不断调用beforeUpdate,updated)

注意:可能有同学又会想到在计算属性中调用接口,计算属性的设计初衷是同步的,计算属性中不应该进行异步请求