@TOC
Vue3要来了Vue2就要过时了吗
Vue3
Vue3尚未发布,还在开发中 面试会考察候选人对新技术的关注程度(Vue太热门) 新版本发布之后,再做补充
Vue2.x马上就要过时了吗
Vue3从正式发布到推广开发,还需要一段时间 Vue2.x应用范围非常广,有大量项目需要维护、升级 Proxy存在浏览器兼容性问题,且不能polyfill
Vue3升级内容
全部用ts重写(响应式、vdom、模板编译等) 性能提升,代码量减少 会调整部分API
Proxy实现响应式
回顾Object.defineProperty Proxy实现响应式 两者对比
Object.defineProperty的缺点
回深度监听需要一次性递归 无法监听新增属性/删除属性(Vue.set Vue.delete) 无法原生监听数组,需要特殊处理
Proxy实现响应式
基本使用 Reflect 实现响应式
Proxy基本使用
// const data = {
// name: 'zhangsan',
// age: 20,
// }
const data = ['a', 'b', 'c']
const proxyData = new Proxy(data, {
get(target, key, receiver) {
// 只处理本身(非原型的)属性
const ownKeys = Reflect.ownKeys(target)
if (ownKeys.includes(key)) {
console.log('get', key) // 监听
}
const result = Reflect.get(target, key, receiver)
return result // 返回结果
},
set(target, key, val, receiver) {
// 重复的数据,不处理
if (val === target[key]) {
return true
}
const result = Reflect.set(target, key, val, receiver)
console.log('set', key, val)
// console.log('result', result) // true
return result // 是否设置成功
},
deleteProperty(target, key) {
const result = Reflect.deleteProperty(target, key)
console.log('delete property', key)
// console.log('result', result) // true
return result // 是否删除成功
}
})
Reflect作用
和Proxy能力一一对应
规范化、标准化、函数式
替代掉Object上的工具函数
Vue3用Proxy实现响应式
Proxy实现响应式
深度监听,性能更好 可监听新增/删除属性 可监听数组变化
// 创建响应式
function reactive(target = {}) {
if (typeof target !== 'object' || target == null) {
// 不是对象或数组,则返回
return target
}
// 代理配置
const proxyConf = {
get(target, key, receiver) {
// 只处理本身(非原型的)属性
const ownKeys = Reflect.ownKeys(target)
if (ownKeys.includes(key)) {
console.log('get', key) // 监听
}
const result = Reflect.get(target, key, receiver)
// 深度监听
// 性能如何提升的?
return reactive(result)
},
set(target, key, val, receiver) {
// 重复的数据,不处理
if (val === target[key]) {
return true
}
const ownKeys = Reflect.ownKeys(target)
if (ownKeys.includes(key)) {
console.log('已有的 key', key)
} else {
console.log('新增的 key', key)
}
const result = Reflect.set(target, key, val, receiver)
console.log('set', key, val)
// console.log('result', result) // true
return result // 是否设置成功
},
deleteProperty(target, key) {
const result = Reflect.deleteProperty(target, key)
console.log('delete property', key)
// console.log('result', result) // true
return result // 是否删除成功
}
}
// 生成代理对象
const observed = new Proxy(target, proxyConf)
return observed
}
// 测试数据
const data = {
name: 'zhangsan',
age: 20,
info: {
city: 'beijing',
a: {
b: {
c: {
d: {
e: 100
}
}
}
}
}
}
const proxyData = reactive(data)
性能如何提升的? 只有get时递归,而且不是一次性递归,获取proxyData.info时只会到city和a这一层,不会到b、c、d、e这一层
总结
Proxy能规避Object.defineProperty的问题 Proxy无法兼容所有浏览器,无法polyfill