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

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)

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

### Vue 中父组件触发子组件数据重新渲染的方法 在 Vue 应用程序中,为了使父组件能够成功触发子组件的数据重新渲染,可以采用多种策略来实现这一目标。 #### 使用 `v-if` 控制子组件显示隐藏 通过设置一个布尔类型的标志位变量控制子组件的销毁与创建过程。当需要更新时,将该标志位置为假使得子组件被移除;随后利用 `nextTick()` 函数等待 DOM 更新完成后再次将其置为真从而重建子组件实例并执行其内部逻辑[^2]。 ```javascript let flag = ref(true); // 当收到新的 prop ... flag.value = false; await nextTick(); flag.value = true; ``` #### 利用 `:key` 动态绑定键强制重绘 每当希望引起一次完整的子组件替换而非简单的属性更改,则可以在模板标签上附加唯一的 `:key` 属性。通常情况下可以选择当前时间戳作为此唯一标识符以确保每次变化都会导致新旧两个不同版本之间的切换操作发生[^4]。 ```html <ChildComponent :propName="parentValue" :key="(new Date()).getTime()" /> ``` #### 处理复杂对象的变化检测 对于那些由父级传递下来的较为复杂的结构化信息(比如嵌套的对象或列表),仅依靠默认机制可能无法及时感知到其中深层字段发生的任何改动。因此建议开发者们考虑借助于浅拷贝或是深克隆技术手动复制一份副本交给子方处理,以此方式间促使视图层面上产生相应的调整动作[^3]。 #### 子组件内侦听 Prop 变更 为了让子组件能够在接收到新的 props 后立即做出响应,可在子组件定义周期钩子函数 `watch` 或者组合式 API 的相应替代品——即 `watchEffect` 来监视特定参数的状态转变事件,并据此调用必要的回调函数完成预期的任务流程[^1]。 ```typescript import { watch, onMounted } from 'vue'; export default { props: ['cityId'], setup(props) { const getData = () => {/* 获取数据显示 */}; watch(() => props.cityId, (newValue, oldValue) => { console.log(`City ID changed from ${oldValue} to ${newValue}`); getData(); // 调用获取最新数据的方法 }); onMounted(() => { getData(); // 组件挂载时也应初始化加载数据 }); return {}; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值