console.log(`get foo:${val}`);
return val
},
set(newVal) {
if (newVal !== val) {
console.log(`set foo:${newVal}`);
val = newVal
}
}
})
}
当我们访问`foo`属性或者设置`foo`值的时候都能够触发`setter`与`getter`
obj.foo
obj.foo = ‘new’
但是我们为`obj`添加新属性的时候,却无法触发事件属性的拦截
obj.bar = ‘新属性’
原因是一开始`obj`的`foo`属性被设成了响应式数据,而`bar`是后面新增的属性,并没有通过`Object.defineProperty`设置成响应式数据
### 三、解决方案
`Vue` 不允许在已经创建的实例上动态添加新的响应式属性
若想实现数据与视图同步更新,可采取下面三种解决方案:
* Vue.set()
* Object.assign()
* $forcecUpdated()
#### Vue.set()
Vue.set( target, propertyName/index, value )
参数
* `{Object | Array} target`
* `{string | number} propertyName/index`
* `{any} value`
返回值:设置的值
通过`Vue.set`向响应式对象中添加一个`property`,并确保这个新 `property` 同样是响应式的,且触发视图更新
关于`Vue.set`源码(省略了很多与本节不相关的代码)
源码位置:`src\core\observer\index.js`
function set (target: Array | Object, key: any, val: any): any {
…
defineReactive(ob.value, key, val)
ob.dep.notify()
return val
}
这里无非再次调用`defineReactive`方法,实现新增属性的响应式
关于`defineReactive`方法,内部还是通过`Object.defineProperty`实现属性拦截
大致代码如下:
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(get ${key}:${val}
);
return val
},
set(newVal) {
if (newVal !== val) {
console.log(set ${key}:${newVal}
);
val = newVal
}
}
})
}
#### Object.assign()
直接使用`Object.assign()`添加到对象的新属性不会触发更新
应创建一个新的对象,合并原对象和混入对象的属性
this.someObject = Object.assign({},this.someObject,{newProperty1:1,newProperty2:2 …})
#### $forceUpdate
如果你发现你自己需要在 `Vue` 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事
`$forceUpdate`迫使 `Vue` 实例重新渲染
PS:仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
#### 小结
### 最后
编程基础的初级开发者,计算机科学专业的学生,以及平时没怎么利用过数据结构与算法的开发人员希望复习这些概念为下次技术面试做准备。或者想学习一些计算机科学的基本概念,以优化代码,提高编程技能。这份笔记都是可以作为参考的。
**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**
![名不虚传!字节技术官甩出的"保姆级"数据结构与算法笔记太香了](https://img-blog.csdnimg.cn/img_convert/a3e940acdcd55765852a8bfe54482664.png)