reactive原理
如果不是浅对象,则需要进一步代理,在get中有个isObject做判断,但是和vue2不同的是,这里如果没有值访问到更加深层的对象属性,就没有触发get里面的进一步深层次代理 就是懒代理 没有访问就不代理 访问了就代理
const toProxy = new WeakMap() // 形如obj:observed
const toRaw = new WeakMap() // 形如observed:obj
const isObject = val => val !== null && typeof val === 'object'
function reactive(obj) {
if (typeof obj !== 'object' && obj != null) {
return obj
}
if (toProxy.has(obj)) {
return toProxy.get(obj)
}
if (toRaw.has(obj)) {
return obj
}
const observed = new Proxy(obj, {
get(target, key, receiver) {
const res = Reflect.get(target, key, receiver)
console.log(`获取${key}:${res}`)
return isObject(res) ? reactive(res) : res // 深层次递归
},
set(target, key, value, receiver) {
const res = Reflect.set(target, key, value, receiver)
console.log(`设置${key}:${value}`)
return res
},
deleteProperty(target, key) {
const res = Reflect.deleteProperty(target, key)
console.log(`删除${key}:${res}`)
return res
}
})
// 缓存代理结果
toProxy.set(obj, observed)
toRaw.set(observed, obj)
return observed
}
测试代码
const state = reactive({
foo: 'foo',
bar: { a: 1 }
})
// 1.获取
state.foo // ok
// 2.设置已存在属性
state.foo = 'fooooooo' // ok
// 3.设置不存在属性
state.dong = 'dong' // ok
// 4.删除属性
delete state.dong // ok
// 测试效果
console.log(reactive(state) === state)
toRefs
对比mixins,好处显而易见:
- time来源清晰
- 不会与data、props等命名冲突
const { createApp, reactive, onMounted, toRefs } = Vue;
createApp({
template: "<p>time: {{time}}</p>",
setup() {
const state = reactive({ time: new Date() })//针对原始值得响应式
onMounted(() => {
setInterval(() => {
state.time = new Date()
}, 1000)
})
const { time } = toRefs(state)
return { time }
}
}).mount('#app')
vue3特性
1、更快:
虚拟DOM重写
优化slots的生成
静态树提升
静态属性提升
基于Proxy的响应式系统
2、更小: 通过摇树优化核心库体积
3、更容易维护: TypeScript + 模块化
4、更加友好:
跨平台:编译器核心和运行时核心与平台无关,使得Vue更容易与任何平台(Web、
Android、iOS)一起使用
5、更容易使用
改进的TypeScript支持,编辑器能提供强有力的类型检查和错误及警告
更好的调试支持
独立的响应化模块
Composition API
虚拟 DOM 重写----------期待更多的编译时提示来减少运行时开销,使用更有效的代码来创建虚拟节点。
组件快速路径+单个调用+子节点类型检测
跳过不必要的条件分支
JS引擎更容易优化
优化slots生成 -----------vue3中可以单独重新渲染父级和子级
确保实例正确的跟踪依赖关系
避免不必要的父子组件重新渲染
静态树提升(Static Tree Hoisting)---------使用静态树提升,这意味着 Vue 3 的编译器将能够检测到什么是静态的,然后将其提升,从而降低了渲
染成本。
跳过修补整棵树,从而降低渲染成本
即使多次出现也能正常工作
静态属性提升 ----------------------------- 使用静态属性提升,Vue 3打补丁时将跳过这些属性不会改变的节点。
基于 Proxy 的数据响应式 ----------- Vue 2的响应式系统使用 Object.defineProperty 的getter 和 setter。Vue 3 将使用 ES2015 Proxy 作为其观察机制,这将会带来如下变化:
组件实例初始化的速度提高100%
使用Proxy节省以前一半的内存开销,加快速度,但是存在低浏览器版本的不兼容
为了继续支持 IE11,Vue 3 将发布一个支持旧观察者机制和新 Proxy 版本的构建
高可维护性 --------- Vue 3 将带来更可维护的源代码。它不仅会使用 TypeScript,而且许多包被解耦,更加模块化。