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 给子组件加key,key变化时子组件会重新渲染
1.2 给子组件加v-if,绑定的值在true,false中方切换时子组件会重新渲染
-
如果子组件中的数据只有部分是请求接口返回的数据,可以选择重新渲染子组件,也可以更新子组件中部分数据
2.1 给子组件加ref,父组件通过ref调用子组件中的请求后端数据的方法
2.2 在子组件中加watch(vue3中也可以用watchEffect),监听props,并调用接口
注意:接口返回的数据在template中绑定时,不要企图在beforeUpdate,updated生命周期函数中再次调用接口,以便进行子组件更新,如果这样做浏览器可能会进入死循环(因为返回的数据会触发响应式,导致vue不断调用beforeUpdate,updated)
注意:可能有同学又会想到在计算属性中调用接口,计算属性的设计初衷是同步的,计算属性中不应该进行异步请求