vue2中为什么修改数据不重新渲染?

今天在写vue项目时发现了几个问题,困扰了我,花时间研究了一下,做个笔记:

1.组件状态没有定义成响应式的数据,更改时不会更新视图,

        什么是响应式数据?怎么定义响应式数据?其实很简单,定义在data里面的数据就是响应式的,更新这里面的数据时,应用这个数据的地方会重新渲染更新视图,达到响应式数据的目的。这是因为vue在初始化的时候initData()时对data里面的数据添加了getter和setter,getter会收集应用这个数据的dep(依赖),setter时会通知dep更新,这里就不展开说明了,以后研究明白了再说。


2.对象增加没有定义成响应式数据的时候不会更新视图,

        这个原因很简单,对象增加新的没有定义多的字段时,这个字段没有经过initData()初始化,没有getter和setter属性,所以不是响应式数据。


3.父组件通过props传递对象数据到子组件时:增加没有定义成响应式属性时父组件不更新视图导致子组件也不会更新props,导致子组件拿不到最新props、也不会更新视图,

        其实这个和2中的原因类似,增加非响应式字段,父组件不会更新视图,导致子组件也不会更新,自然就获取不到最新的props。


4.通常情况下vue会收集setData在合适的时机统一更新视图,但使用了await关键字的异步方法的then()里面的setData会单独更新视图,不与外面的setData同时更新

         这个暂时还不知道原因,后面再更新


解决方法:


①.通常可以使用$set()解决对象新增未定义的属性,

$set()是vue公开的添加响应式属性的api,有三个参数

(1:要修改的对象,2:这个对象要修改或增加的字段名,3:这个字段的值)

例:$set(obj,key,value)

②.使用ES6的解构赋值obj={...obj,newKey:value},其实这个能触发视图更新的原因是因为修改了obj,obj定义在data中,始终是响应式数据,所以能触发重新渲染。

---------------------------------------------------------------------------------------------------------------------------------

今天发现了一个小程序中vue的一个差异,当在父组件绑定一个obj数据时,通过props传递给子组件,通过方法修改这个obj:

handleModify(){

this.obj = {a:1,b:2}

}

重复触发这个方法,父组件中每次都会触发obj的watch和update生命周期,但是子组件只有第一次会触发obj的watch,update生命周期一直不触发,

但是在web端是每次都会触发父组件和子组件中obj的watch和update生命周期??这就很神奇!!

Vue 中,强制重新渲染组件可以通过多种方式实现。Vue 的响应式系统通常会自动追踪依赖并更新视图,但在某些特定场景下可能需要手动干预以确保组件状态的同步更新。 ### 使用 `$forceUpdate()` 强制更新 Vue 提供了 `$forceUpdate()` 方法用于强制组件重新渲染。该方法会跳过虚拟 DOM 的优化策略,直接触发组件及其子组件的重新渲染。需要注意的是,应谨慎使用此方法,因为它可能会破坏数据流的清晰性。 ```javascript this.$forceUpdate(); ``` 这种方式适用于组件状态未通过响应式数据绑定更新的情况[^1]。 ### 利用 `key` 属性控制组件实例 另一种常见做法是通过修改组件的 `key` 属性来强制 Vue 重新创建组件实例。当 `key` 值发生变化时,Vue 会销毁旧的组件实例并创建新的实例,从而达到重新渲染的目的。 ```vue <template> <my-component :key="componentKey" /> </template> ``` 在需要更新组件时,只需改变 `componentKey` 的值: ```javascript this.componentKey = Math.random(); ``` 这种方法比 `$forceUpdate()` 更加声明式,并且会影响其他组件的状态[^2]。 ### 避免非响应式数据导致的更新失败 如果组件的更新依赖于某个变量,而该变量未被正确地定义为响应式(例如未在 `data()` 或 `computed` 中声明),则 Vue 无法检测到变化并触发重新渲染。因此,确保所有用于驱动视图的数据都是响应式的至关重要。 ```vue <template> <div>{{ message }}</div> </template> <script> export default { data() { return { message: 'Initial message' }; }, methods: { updateMessage(newMessage) { this.message = newMessage; } } }; </script> ``` 若数据未按上述方式定义,则可能导致组件无法更新[^5]。 ### 调试与工具支持 在调试组件更新问题时,可以借助 Vue DevTools 检查组件的 props、data 和 computed 属性是否正常更新。此外,确保相关依赖如 Vue Router、Vuex 等库版本兼容当前 Vue 核心版本,以避免因库之间的兼容导致更新机制失效[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值