Vue3.0设计目标
- 更小
- 更快(*)
- 加强TypeScript支持(*)
- 加强API设计一致性
- 提高自身可维护性
- 开放更多底层功能
更快
- Object.defineProperty -> Proxy (颗粒度更大)
- Virtual Dom 重构
- 更多编译优化:slot默认编译为函数(不存在父子组件强耦合),Momomorphic vnode factory,Compiler-generated flags for vnode/children types
Virtual Dom 重构
传统Virtual DOM的性能瓶颈
颗粒度是组件。
虽然Vue能够保证触发更新的组件最小化,但是单个组件内部依然需要遍历该组件的整个Virtual DOM树。
传统Virtual DOM的性能跟模板大小正相关,跟动态节点的数量无关。在一些组件整个模板内只有少量动态节点的情况下,这些遍历都是性能的浪费。
Vue3.0 Virtual DOM
动静结合
- 节点结构完全不会改变
- 只有一个动态节点
节点结构变化 v-if
- v-if 外部:只有v-if是动态节点
- v-if 内部:只有 {{ message }} 是动态节点
节点结构变化 v-for
- v-for 外部:只有v-for是动态节点 (fragment)
- 每个v-for循环内部:只有 {{ item.message }} 是动态节点
区块树Block tree
- 将模板基于动态节点指令切割为嵌套的区块
- 每个区块内部的节点结构是固定的
- 每个区块只需要以一个Array追踪自身包含的动态节点
升级
新策略将Virtual DOM更新性能能由与模板整体大小相关提升为与动态内容的数量相关
TypeScript(略)
API设计
Fuction-based API
const App = { setup() { // data const count = value(0) // computed const plusOne = computed(() => count.value + 1) // method const increment = () => { count.value++ } // watch watch(() => count.value * 2, v => console.log(v)) // lifecycle onMounted(() => console.log('mounted!')) // 暴露给模板或渲染函数 return { count } } } 复制代码
优点
- 没有命名空间冲突
- 数据来源清晰
- 没有额外的组件性能消耗
对比Class API
- 更好的TypeScript类型推导支持
- 更灵活的逻辑复用能力
- Tree-shaking友好
- 代码更容易被压缩
更灵活的逻辑复用能力
鼠标位置侦听:
定义
function useMousePosition() { const x = value(0) const y = value(0) const update = e => { x.value = e.pageX y.value = e.pageY } onMounted(() => { window.addEventListener('mousemove', update) }) onUnmounted(() => { window.removeEventListener('mousemove', update) }) return { x, y } } 复制代码
使用
new Vue({ template: ` <div> Mouse position: x {{ x }} / y {{ y }} </div> `, setup() { const { x, y } = useMousePosition() return { x, y } } }) 复制代码
对比React Hooks
- 同样的逻辑组合、复用能力
- Vue只调用一次,符合js直觉,没有闭包变量问题,没有内存/GC压力,不存在内联回调导致子组件永远更新的问题
本文暂时没有评论,来添加一个吧(●'◡'●)