前端面试:Vue中给对象添加新属性页面不刷新原因及解决方案

vue2是用过Object.defineProperty实现数据响应式

const obj = {}
Object.defineProperty(obj, 'foo', {
        get() {
            console.log(`get foo:${val}`);
            return val
        },
        set(newVal) {
            if (newVal !== val) {
                console.log(`set foo:${newVal}`);
                val = newVal
            }
        }
    })
}

 当我们访问foo属性或者设置foo值的时候都能够触发settergetter

obj.foo   
obj.foo = 'new'

 但是我们为obj添加新属性的时候,却无法触发事件属性的拦截

obj.bar  = '新属性'

原因是一开始objfoo属性被设成了响应式数据,而bar是后面新增的属性,并没有通过Object.defineProperty设置成响应式数据

解决方案

Vue.set()

Vue.set( target, propertyName/index, value )

Object.assign()

直接使用Object.assign()添加到对象的新属性不会触发更新。应创建一个新的对象,合并原对象和混入对象的属性

this.someObject = Object.assign({},this.someObject,{newProperty1:1,newProperty2:2 ...})

$forceUpdate

如果你发现你自己需要在 Vue 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事

$forceUpdate迫使 Vue 实例重新渲染(不推荐使用)