一、类型系统设计扩展说明
1.1 Props 类型推导增强
typescript
// 复杂嵌套类型支持
interface Address {
city: string
postalCode: string
}
interface UserProfile {
id: number
name: string
addresses: Address[]
}
export default defineComponent({
props: {
profile: {
type: Object as PropType<UserProfile>,
validator: (value: UserProfile) => {
return value.addresses.every(addr => addr.postalCode.match(/^\d{6}$/))
}
}
},
setup(props) {
// 完整类型提示链
props.profile?.addresses[0]?.city // string | undefined
}
})
实现原理:
PropType<T>
通过类型断言保留类型信息- 验证器函数自动继承泛型类型参数
- 递归类型展开支持嵌套对象结构
1.2 Composition API 类型扩展
typescript
import { Ref, ref, watchEffect } from 'vue'
// 带自动卸载的逻辑复用
export function useMouseTracker(): { x: Ref<number>, y: Ref<number> } {
const x = ref(0)
const y = ref(0)
const update = (e: MouseEvent) => {
x.value = e.clientX
y.value = e.clientY
}
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
return { x, y }
}
// 使用示例
const { x, y } = useMouseTracker()
watchEffect(() => {
console.log(`Cursor at (${x.value}, ${y.value})`)
})
类型机制:
Ref<T>
接口定义响应式引用类型- 返回值类型声明确保组合函数类型安全
- 生命周期钩子自动集成类型系统
二、运行时核心架构深度解析
2.1 响应式系统完整实现
typescript
// reactivity/src/reactive.ts 核心实现
export function reactive<T extends object>(target: T): T {
const proxy = new Proxy(target, {
get(target, key, receiver) {
track(target, key)
const res = Reflect.get(target, key, receiver)
return isObject(res) ? reactive(res) : res
},
set(target, key, value, receiver) {
const oldValue = (target as any)[key]
const result = Reflect.set(target, key, value, receiver)
if (result && oldValue !== value) {
trigger(target, key)
}
return result
}
})
return proxy as T
}
// 依赖跟踪实现
const targetMap = new WeakMap<any, KeyToDepMap>()
function track(target: object, key: unknown) {
if (activeEffect) {
let depsMap = targetMap.get(target)
if (!depsMap) {
targetMap.set(target, (depsMap = new Map()))
}
let dep = depsMap.get(key)
if (!dep) {
depsMap.set(key, (dep = new Set()))
}
dep.add(activeEffect)
}
}
核心优化:
- 嵌套对象自动代理(Lazy Proxy)
- 基于 WeakMap 的依赖存储结构
- 精确的变更检测机制
2.2 虚拟 DOM Diff 算法优化
javascript
// runtime-core/src/vnode.ts
const patchFlagNames = {
[1 << 0]: 'TEXT',
[1 << 1]: 'CLASS',
[1 << 2]: 'STYLE',
// ...其他标志位
}
function diffChildren(oldVnode, newVnode, container) {
const oldChildren = oldVnode.children || []
const newChildren = newVnode.children || []
// 快速路径:仅文本子节点更新
if (newVnode.patchFlag & PatchFlags.TEXT_CHILDREN) {
container.textContent = newVnode.children
return
}
// 键控对比算法
let oldStartIdx = 0, newStartIdx = 0
let oldEndIdx = oldChildren.length - 1
let newEndIdx = newChildren.length - 1
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
// ... 省略具体比对逻辑
}
}
性能优化:
- 基于位运算的静态标记(PatchFlags)
- 最长递增子序列算法应用
- 按需更新策略(动态节点追踪)
2.3 编译器优化案例 模板编译前:
html
<div>
<span>Static</span>
<div :class="{ active: isActive }">{{ dynamic }}</div>
</div>
编译后优化代码:
javascript
import { createElementVNode as _createElementVNode,
normalizeClass as _normalizeClass,
toDisplayString as _toDisplayString,
openBlock as _openBlock,
createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", null, [
_createElementVNode("span", null, "Static"),
_createElementVNode("div", {
class: _normalizeClass({ active: _ctx.isActive })
}, _toDisplayString(_ctx.dynamic), 3 /* TEXT, CLASS */)
]))
}
优化特征:
- 静态节点提升(Hoist Static)
- 补丁标志位(3 表示同时需要 TEXT 和 CLASS 更新)
- 缓存事件处理程序
三、完整响应式工作流示例
typescript
// 创建响应式对象
const state = reactive({
count: 0,
items: [] as string[]
})
// 副作用函数
const effect = () => {
console.log(`Count: ${state.count}, Items: ${state.items.join(',')}`)
}
// 手动触发依赖收集
let activeEffect: Function | null = effect
activeEffect()
activeEffect = null
// 触发更新
state.count++ // 打印更新日志
state.items.push('new item') // 触发数组修改的代理
执行流程:
- 初始化时
effect
函数访问响应式属性 - Proxy getter 触发
track
记录依赖 - 数据变更时 Proxy setter 调用
trigger
- 触发存储的 effect 重新执行
四、自定义渲染器实现
typescript
// 创建 Canvas 渲染器
const { createRenderer } = require('@vue/runtime-core')
const nodeOps = {
createElement(type) {
return document.createElementNS('http://www.w3.org/2000/svg', type)
},
insert(child, parent) {
parent.appendChild(child)
},
setElementText(el, text) {
el.textContent = text
}
// ...其他 DOM 操作方法
}
const renderer = createRenderer(nodeOps)
// 使用自定义渲染器
const vnode = {
type: 'rect',
props: {
x: 10,
y: 10,
width: 100,
height: 100,
fill: 'red'
}
}
renderer.render(vnode, document.getElementById('app'))
架构优势:
- 核心模块与平台代码解耦
- 支持跨平台渲染(Canvas、WebGL等)
- 保持核心响应式系统不变