Vue - 你知道Vue2中对象动态新增属性,视图无法更新的原因吗

文章讲述了在Vue项目中,当动态添加新属性时视图未更新的原因——新属性未被响应式监听。提供了解决方案,包括使用$forceUpdate()强制更新和Vue.set()方法添加新属性并通知视图更新。
摘要由CSDN通过智能技术生成

难度级别:中高级及以上                               提问概率:55% 


这道题面试官会这样描述,比如有这样一个场景,一个对象里有name属性,可以正常显示在页面中。但后续动态添加了一个age属性,通过调试打印发现对象里的age属性已经添加了上了,但试图中却没有展示出来,请你说一说原因。

在Vue项目中一旦发现试图没有更新,首先要排查的就是数据是否已更新,不过本题已经帮助排查过了,那么问题很可能出现在Vue针对数据变更的响应式监听上。在Vue组件中,我们会提前定义一些data数据依赖,Vue在做初始化双向数据绑定的时候,会针对数据依赖的属性进行响应式监听,然后通过Vue指令将template模板中的变量与data数据依赖绑定起来,主要核心原理使用的就是Object的defineProperty方法。那么回归到本题上,响应式监听核心代码就像这样

Javascript代码:
<script>
cosnt people = {
        name: '张三'
    };
    Object.defineProperty(people, 'name', {
get() {
return val;
},
set(newVal) {
if (newVal !== val) {
val = newVal;
}
}
})
    setTimeout(() => {
        people['age'] = 25;
}, 3000)
</script>

因为在Vue初始实例的时候,defineProperty方法针对的是对象属性,所以属性新增后,新属性并不能被监听到,也就是无法被响应到试图模板中了。那么有哪些方法可以达到更新的效果呢?我们一起来看一下。

首先最简单粗暴的方案就是使用$forceUpdate()方法,进行组件强制更新,它其实是触发了组件的update方法,并不会使组件整体再更新一遍,也就是created、mounted这些生命周期并不会被触发。

另一种方案是使用Vue.set()方法,这个方法接收3个参数,分别是要修改的对象、属性和属性值。set方法首先确认当前传入的对象是否属于响应式对象,如果不是响应式对象,则只是单纯的为目标对象赋值即可,如果是响应式对象,这里就需要调用核心方法defineReactive,这个方法内部则是再次执行Object.defineProperty方法,将新增的属性添加到响应式对象中去。这还没有结束,新的响应属性添加完成了,在源码文件\node_modules\vue\src\core\observer\index.js中,通过ob.dep.notify()手动更新试图即可。


刷题思考

    这道题是Vue2中的一道经典面试题,关于对象动态添加属性视图无法更新的问题,在面试的时候,要把我住两点,第一就是讲述自己遇到的项目场景和解决方案,而这也只是基础回答,将问题出现的原因和set()方法的原理描述清除,才能算作标准回答。


类似考点

    Vue2其实还有很多经典的问题,虽然在Vue3中得到了解决,但肯定还是有面试官会问类似的问题,例如请你说一说,Vue2监听数组变化的时候会遇到哪些问题?例如请你说一说,$nextTick的使用场景有哪些?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

经海路大白狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值