最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入解析Vue包之vue各子包究竟導(dǎo)出了什么

 更新時(shí)間:2026年06月01日 09:41:59   作者:來(lái)碗疙瘩湯  
這篇文章主要介紹了vue各子包究竟導(dǎo)出了什么的相關(guān)資料,文中通過(guò)代碼介紹了Vue3架構(gòu)的核心價(jià)值與實(shí)際應(yīng)用場(chǎng)景,適合Vue開(kāi)發(fā)者深入了解框架底層機(jī)制,需要的朋友可以參考下

前言

本文系統(tǒng)梳理 Vue 3 各子包(vue、@vue/reactivity@vue/runtime-core、@vue/runtime-dom、@vue/compiler-core@vue/compiler-dom、@vue/shared)的完整導(dǎo)出結(jié)構(gòu),重點(diǎn)覆蓋官方文檔未詳細(xì)說(shuō)明、日常開(kāi)發(fā)中被忽視但架構(gòu)價(jià)值極高的 API。

一、Vue 包體系全景:Monorepo 架構(gòu)

很多開(kāi)發(fā)者誤認(rèn)為 vue 是一個(gè)完整的實(shí)現(xiàn)包,實(shí)則它只是一個(gè) Facade(門面模塊)

vue(聚合導(dǎo)出層)
│
├── @vue/runtime-dom        ← 瀏覽器平臺(tái)渲染層
│    └── @vue/runtime-core  ← 平臺(tái)無(wú)關(guān)運(yùn)行時(shí)
│         └── @vue/reactivity ← 純響應(yīng)式系統(tǒng)
│
├── @vue/compiler-dom       ← 瀏覽器模板編譯器
│    └── @vue/compiler-core ← 平臺(tái)無(wú)關(guān)編譯器
│
└── @vue/shared             ← 內(nèi)部共享工具函數(shù)

每個(gè)子包都可以獨(dú)立安裝使用,這正是 Vue 3 架構(gòu)解耦的核心體現(xiàn)。

二、@vue/reactivity:獨(dú)立響應(yīng)式引擎

這是 Vue 3 最具突破性的設(shè)計(jì)——響應(yīng)式系統(tǒng)與框架完全解耦,可以在任何 JS 環(huán)境中獨(dú)立使用。

npm install @vue/reactivity

2.1 核心響應(yīng)式原語(yǔ)

ref/shallowRef/customRef

import { ref, shallowRef, customRef } from '@vue/reactivity'

// 標(biāo)準(zhǔn) ref:深度響應(yīng)
const state = ref({ a: { b: 1 } })

// shallowRef:只有 .value 本身是響應(yīng)式,內(nèi)部屬性不追蹤
const shallow = shallowRef({ count: 0 })
shallow.value.count++ // 不觸發(fā)更新
shallow.value = { count: 1 } // 觸發(fā)更新

// customRef:完全自定義追蹤時(shí)機(jī)(防抖、節(jié)流場(chǎng)景極為有用)
function useDebouncedRef(value, delay = 200) {
  let timer
  return customRef((track, trigger) => ({
    get() {
      track() // 手動(dòng)聲明依賴追蹤
      return value
    },
    set(newValue) {
      clearTimeout(timer)
      timer = setTimeout(() => {
        value = newValue
        trigger() // 手動(dòng)觸發(fā)更新
      }, delay)
    }
  }))
}

customRef 是實(shí)現(xiàn)防抖輸入、異步數(shù)據(jù)源等場(chǎng)景的底層利器,但鮮少被人使用。

reactive/shallowReactive/readonly/shallowReadonly

import { reactive, shallowReactive, readonly, shallowReadonly } from '@vue/reactivity'

// shallowReactive:只追蹤頂層屬性,不深度轉(zhuǎn)換
const state = shallowReactive({
  user: { name: 'Tom' } // user.name 的變化不會(huì)觸發(fā)更新
})

// readonly:深度只讀代理,任何寫入都會(huì)在 dev 環(huán)境報(bào)警告
const config = readonly({ api: 'https://example.com' })

// shallowReadonly:只有頂層只讀,嵌套對(duì)象仍可修改
const mixed = shallowReadonly({ nested: { value: 1 } })
mixed.nested.value = 2 // 允許(不報(bào)警告)
mixed.nested = {} // 阻止(報(bào)警告)

2.2 副作用系統(tǒng)底層 API(極少被直接使用)

effect/ReactiveEffect

effect 是 Vue 響應(yīng)式系統(tǒng)最底層的副作用原語(yǔ),computed、watch 都是基于它構(gòu)建的。

import { effect, reactive } from '@vue/reactivity'

const state = reactive({ count: 0 })

// effect 會(huì)立即執(zhí)行,并自動(dòng)追蹤其中訪問(wèn)的響應(yīng)式數(shù)據(jù)
const runner = effect(() => {
  console.log('count is:', state.count)
})

state.count++ // 自動(dòng)重新執(zhí)行 effect

// 手動(dòng)停止追蹤
runner.effect.stop()

effectScope/getCurrentScope/onScopeDispose

這組 API 是 Vue 3.2 引入的副作用作用域管理機(jī)制,專為編寫可復(fù)用組合函數(shù)設(shè)計(jì),但日常業(yè)務(wù)代碼中極少被直接使用。

import { effectScope, getCurrentScope, onScopeDispose } from '@vue/reactivity'

// 創(chuàng)建一個(gè)作用域,批量管理所有 effect/watch/computed
const scope = effectScope()

scope.run(() => {
  const doubled = computed(() => count.value * 2)
  watchEffect(() => console.log(doubled.value))
})

// 一次性停止作用域內(nèi)所有副作用——無(wú)需逐一手動(dòng) stop()
scope.stop()

架構(gòu)價(jià)值:在大型組合函數(shù)庫(kù)(如 VueUse)中,effectScope 是正確管理副作用生命周期的標(biāo)準(zhǔn)方式,避免內(nèi)存泄漏。

// 在自定義組合函數(shù)中使用
function useFeature() {
  const scope = effectScope()
  
  scope.run(() => {
    // 所有 effect 在這里注冊(cè)
    onScopeDispose(() => {
      // scope 被 stop 時(shí)的清理邏輯
      scope.stop()
    })
  })
  
  return scope
}

pauseTracking/resumeTracking/resetTracking

這組 API 允許手動(dòng)控制依賴追蹤的暫停與恢復(fù),是構(gòu)建高級(jí)響應(yīng)式工具的基礎(chǔ)。

import { pauseTracking, resetTracking, effect } from '@vue/reactivity'

effect(() => {
  state.a // 正常追蹤
  
  pauseTracking()
  state.b // 訪問(wèn)但不追蹤,state.b 變化不會(huì)觸發(fā) re-run
  resetTracking()
  
  state.c // 恢復(fù)正常追蹤
})

實(shí)際應(yīng)用場(chǎng)景:在實(shí)現(xiàn) readonly 包裝、不希望某些讀操作建立依賴時(shí)使用。

trackOpBit/triggerRef

import { ref, triggerRef } from '@vue/reactivity'

// triggerRef:強(qiáng)制觸發(fā) shallowRef 的更新(直接修改內(nèi)部結(jié)構(gòu)后手動(dòng)通知)
const state = shallowRef({ list: [1, 2, 3] })
state.value.list.push(4) // 直接改內(nèi)部,不觸發(fā)更新
triggerRef(state)         // 手動(dòng)強(qiáng)制觸發(fā)

2.3 工具函數(shù)

toRaw/markRaw

import { reactive, toRaw, markRaw } from '@vue/reactivity'

const state = reactive({ data: {} })

// toRaw:獲取響應(yīng)式對(duì)象的原始對(duì)象(繞過(guò) Proxy),用于性能敏感操作
const raw = toRaw(state) // 直接操作,不觸發(fā)任何追蹤

// markRaw:標(biāo)記對(duì)象永不被轉(zhuǎn)為響應(yīng)式(第三方庫(kù)實(shí)例、大型數(shù)據(jù)集等)
const chart = markRaw(new ECharts())
const state2 = reactive({ chart }) // chart 不會(huì)被代理

架構(gòu)意義:在將第三方庫(kù)對(duì)象(如 Canvas 實(shí)例、WebSocket 對(duì)象)放入響應(yīng)式狀態(tài)時(shí),必須用 markRaw 避免性能問(wèn)題。

proxyRefs

import { proxyRefs, ref } from '@vue/reactivity'

// proxyRefs:自動(dòng)解包對(duì)象中的所有 ref(這正是 setup() 返回值的內(nèi)部處理機(jī)制)
const state = { count: ref(0), name: ref('Tom') }
const proxied = proxyRefs(state)

proxied.count // 直接訪問(wèn),無(wú)需 .value(內(nèi)部自動(dòng)解包)

這是 Vue 模板自動(dòng)解包 ref 的底層實(shí)現(xiàn)機(jī)制。

isRef/isReactive/isReadonly/isProxy/isShallow

import { ref, reactive, readonly, isRef, isReactive, isReadonly, isProxy, isShallow, shallowRef } from '@vue/reactivity'

isRef(ref(0))           // true
isReactive(reactive({})) // true
isReadonly(readonly({})) // true
isProxy(reactive({}))    // true(reactive 和 readonly 都是 Proxy)
isShallow(shallowRef(0)) // true(Vue 3.2+ 新增)

unref

import { unref, ref } from '@vue/reactivity'

// unref:安全地獲取 ref 的值,非 ref 原樣返回
function useValue(val) {
  return unref(val) // 不需要判斷 isRef
}

useValue(ref(42)) // 42
useValue(42)      // 42

這是編寫接受 MaybeRef<T> 參數(shù)的組合函數(shù)的標(biāo)準(zhǔn)做法。

toRef/toRefs/toValue(Vue 3.3+)

import { reactive, toRef, toRefs, toValue } from '@vue/reactivity'

const state = reactive({ x: 1, y: 2 })

// toRef:從 reactive 對(duì)象中創(chuàng)建單個(gè)屬性的 ref(保持響應(yīng)式連接)
const xRef = toRef(state, 'x')

// toRefs:將整個(gè) reactive 對(duì)象解構(gòu)為 ref 集合(解構(gòu)時(shí)保持響應(yīng)性的核心工具)
const { x, y } = toRefs(state)

// toValue(3.3+):同 unref,但還能接受 getter 函數(shù)
const val = toValue(() => state.x + 1) // 執(zhí)行 getter 并返回結(jié)果

2.4 計(jì)算屬性底層

computed的完整簽名

import { computed } from '@vue/reactivity'

// 可寫計(jì)算屬性(文檔有提及但很少被用到)
const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: (val) => { count.value = val - 1 }
})

plusOne.value = 10
console.log(count.value) // 9

三、@vue/runtime-core:平臺(tái)無(wú)關(guān)運(yùn)行時(shí)

這是 Vue 組件模型的核心,包含大量未被官方文檔重點(diǎn)介紹的底層 API

3.1 組件內(nèi)部訪問(wèn)

getCurrentInstance

import { getCurrentInstance } from '@vue/runtime-core'

// 只能在 setup() 或生命周期鉤子中調(diào)用
const instance = getCurrentInstance()

// 實(shí)例上有大量?jī)?nèi)部屬性(僅用于框架級(jí)開(kāi)發(fā),生產(chǎn)代碼慎用)
instance.uid          // 組件唯一 ID
instance.type         // 組件定義對(duì)象
instance.parent       // 父組件實(shí)例
instance.root         // 根組件實(shí)例
instance.appContext   // 應(yīng)用上下文(含全局注冊(cè)的組件、指令、插件數(shù)據(jù))
instance.subTree      // 當(dāng)前 vnode 子樹(shù)
instance.isMounted    // 是否已掛載
instance.isUnmounted  // 是否已卸載

場(chǎng)景:編寫需要感知組件樹(shù)的底層庫(kù)(如 Pinia 內(nèi)部通過(guò)它訪問(wèn) appContext)。

useAttrs/useSlots

import { useAttrs, useSlots } from '@vue/runtime-core'

// 在 setup 中訪問(wèn)透?jìng)鞯?attrs 和 slots(等效于選項(xiàng)式 API 的 $attrs/$slots)
const attrs = useAttrs()  // 包含 class, style, 事件監(jiān)聽(tīng)器等非 prop 屬性
const slots = useSlots()  // 包含所有插槽的渲染函數(shù)

useCssModule(與<style module>配合)

import { useCssModule } from '@vue/runtime-core'

// 訪問(wèn) CSS Modules 的類名映射(通常與 SFC <style module> 配合)
const css = useCssModule()
// css.myClass → 'myClass_hash123_1'(編譯后的哈希類名)

3.2 依賴注入高級(jí)用法

inject的完整簽名與InjectionKey

import { provide, inject, InjectionKey } from '@vue/runtime-core'

// 使用 Symbol 作為類型安全的注入鍵(TypeScript 推薦做法)
const UserKey: InjectionKey<{ name: string }> = Symbol('user')

// 父組件
provide(UserKey, { name: 'Tom' })

// 子組件 - 有完整類型推斷
const user = inject(UserKey)            // User | undefined
const user2 = inject(UserKey, { name: 'Guest' }) // 帶默認(rèn)值,類型為 User
const user3 = inject(UserKey, () => ({ name: 'Guest' }), true) // 工廠函數(shù)(第三個(gè)參數(shù) true 表示是工廠)

3.3 VNode 操作 API

h渲染函數(shù)的完整能力

import { h, resolveComponent, resolveDirective, withDirectives } from '@vue/runtime-core'

export default {
  render() {
    // 渲染組件
    const MyComp = resolveComponent('MyComp') // 按名稱解析已注冊(cè)的全局組件
    
    // 渲染帶自定義指令的 vnode
    const dir = resolveDirective('my-directive')
    return withDirectives(
      h('div', 'hello'),
      [[dir, value, argument, modifiers]]
    )
  }
}

cloneVNode

import { h, cloneVNode } from '@vue/runtime-core'

// 克隆 VNode 并可覆蓋部分 props(用于高階組件 HOC 模式)
const original = h('div', { class: 'foo' }, 'hello')
const cloned = cloneVNode(original, { class: 'bar', style: 'color: red' })
// 等效于 h('div', { class: ['foo', 'bar'], style: 'color: red' }, 'hello')

mergeProps

import { mergeProps } from '@vue/runtime-core'

// 智能合并多個(gè) props 對(duì)象(class/style 合并,事件監(jiān)聽(tīng)器鏈?zhǔn)秸{(diào)用)
const merged = mergeProps(
  { class: 'a', onClick: handler1 },
  { class: 'b', onClick: handler2 }
)
// { class: ['a', 'b'], onClick: [handler1, handler2] }

這是實(shí)現(xiàn)透?jìng)鲗傩院喜?、封裝 UI 組件庫(kù)的核心工具。

createVNode/openBlock/createBlock/createElementVNode

這些是編譯器輸出的運(yùn)行時(shí)助手函數(shù),通常不應(yīng)在業(yè)務(wù)代碼中直接使用,但理解它們有助于分析編譯產(chǎn)物性能。

// 模板編譯后生成的代碼示意:
import { createElementVNode, openBlock, createElementBlock } from '@vue/runtime-core'

function render() {
  return (openBlock(), createElementBlock("div", null, [
    createElementVNode("span", null, "hello")
  ]))
}

openBlock + createBlock 組合是 Vue 3 **Fragment 優(yōu)化與靶向更新(patch flag)**的基礎(chǔ)。

createTextVNode/createCommentVNode/createStaticVNode

import { createTextVNode, createCommentVNode, createStaticVNode } from '@vue/runtime-core'

createTextVNode('hello')         // 創(chuàng)建文本節(jié)點(diǎn)
createCommentVNode('debug info') // 創(chuàng)建注釋節(jié)點(diǎn)(v-if 的占位符就是它)

// createStaticVNode:將靜態(tài) HTML 字符串作為 vnode(SSR hydration 場(chǎng)景)
createStaticVNode('<div>static content</div>', 1)

3.4 異步組件

defineAsyncComponent完整配置

import { defineAsyncComponent } from '@vue/runtime-core'

const AsyncComp = defineAsyncComponent({
  loader: () => import('./HeavyComponent.vue'),
  
  loadingComponent: LoadingSpinner,  // 加載中顯示的組件
  delay: 200,                        // 顯示 loading 前的延遲(避免閃爍)
  
  errorComponent: ErrorDisplay,      // 加載失敗顯示的組件
  timeout: 3000,                     // 超時(shí)時(shí)間(ms),超時(shí)視為失敗
  
  // 高級(jí):自定義加載函數(shù)(控制重試邏輯)
  onError(error, retry, fail, attempts) {
    if (attempts <= 3) retry() // 最多重試 3 次
    else fail()
  }
})

3.5 內(nèi)置組件的底層實(shí)現(xiàn)

Suspense深度用法

import { Suspense, defineAsyncComponent } from 'vue'
<Suspense>
  <template #default>
    <AsyncComponent />
  </template>
  <template #fallback>
    <LoadingSpinner />
  </template>
</Suspense>

Suspense 還支持與 async setup() 配合:

export default {
  async setup() {
    // setup 可以是異步的,父級(jí) Suspense 會(huì)等待它 resolve
    const data = await fetch('/api/data').then(r => r.json())
    return { data }
  }
}

3.6 調(diào)度器 API

nextTick與內(nèi)部調(diào)度機(jī)制

import { nextTick } from '@vue/runtime-core'

// nextTick 返回 Promise,可在 DOM 更新后執(zhí)行操作
await nextTick()

// 也接受回調(diào)(兼容舊寫法)
nextTick(() => {
  // DOM 已更新
})

queuePostFlushCb(內(nèi)部 API,謹(jǐn)慎使用)

import { queuePostFlushCb } from '@vue/runtime-core'

// 在當(dāng)前刷新周期結(jié)束后異步執(zhí)行回調(diào)(比 nextTick 更底層)
queuePostFlushCb(() => {
  // 所有 DOM 更新和 watchPostEffect 之后執(zhí)行
})

3.7 生命周期擴(kuò)展鉤子

除了常見(jiàn)的八個(gè)生命周期,還有以下較少使用的:

import {
  onRenderTracked,     // 每次響應(yīng)式依賴被追蹤時(shí)觸發(fā)(僅 dev)
  onRenderTriggered,   // 每次重渲染被觸發(fā)時(shí)攜帶具體原因(僅 dev)
  onActivated,         // KeepAlive 激活時(shí)
  onDeactivated,       // KeepAlive 停用時(shí)
  onServerPrefetch,    // SSR:組件 prefetch 數(shù)據(jù)鉤子
  onErrorCaptured,     // 捕獲子孫組件的錯(cuò)誤
} from '@vue/runtime-core'

// onRenderTracked / onRenderTriggered 是性能調(diào)試?yán)?
onRenderTriggered((event) => {
  console.log('觸發(fā)重渲染的原因:', {
    effect: event.effect,
    target: event.target,   // 被修改的對(duì)象
    type: event.type,       // 'set' / 'add' / 'delete'
    key: event.key,         // 被修改的屬性名
    newValue: event.newValue,
    oldValue: event.oldValue,
  })
})

onRenderTrackedonRenderTriggered 是排查不必要重渲染的終極工具,但極少被開(kāi)發(fā)者使用。

3.8defineComponent的類型推斷能力

import { defineComponent, PropType } from '@vue/runtime-core'

// defineComponent 的核心價(jià)值是 TypeScript 類型推斷,而非運(yùn)行時(shí)行為
const MyComp = defineComponent({
  props: {
    user: {
      type: Object as PropType<{ name: string; age: number }>,
      required: true
    },
    // 函數(shù)類型 prop
    onClick: Function as PropType<(id: number) => void>
  },
  emits: {
    // 帶類型驗(yàn)證的 emits 定義
    change: (value: string) => typeof value === 'string',
    submit: null  // 無(wú)驗(yàn)證
  },
  setup(props, { emit, expose, attrs, slots }) {
    // props 此處有完整類型推斷
    expose({ publicMethod() {} }) // 限制對(duì)外暴露的 API
  }
})

3.9 渲染器相關(guān)(高級(jí))

createRenderer/createHydrationRenderer

這是 Vue 跨平臺(tái)渲染的核心 API,允許創(chuàng)建自定義渲染器。

import { createRenderer } from '@vue/runtime-core'

// 創(chuàng)建一個(gè) Canvas 渲染器(偽代碼示意)
const { render, createApp } = createRenderer({
  createElement(type) { /* 創(chuàng)建 Canvas 元素 */ },
  patchProp(el, key, prevVal, nextVal) { /* 更新屬性 */ },
  insert(el, parent, anchor) { /* 插入節(jié)點(diǎn) */ },
  remove(el) { /* 刪除節(jié)點(diǎn) */ },
  createText(text) { /* 創(chuàng)建文本節(jié)點(diǎn) */ },
  setText(node, text) { /* 更新文本 */ },
  // ...其他 DOM 操作
})

這是 Pixi.js、Three.js、Native 渲染器等 Vue 跨平臺(tái)項(xiàng)目的基礎(chǔ) API。

四、@vue/runtime-dom:瀏覽器平臺(tái)層

runtime-core 之上,runtime-dom 提供了瀏覽器專屬能力。

4.1 內(nèi)置指令實(shí)現(xiàn)

這些通常由編譯器自動(dòng)生成,但在 Render Function 場(chǎng)景下需要手動(dòng)導(dǎo)入:

import {
  vModelText,      // <input v-model>
  vModelCheckbox,  // <input type="checkbox" v-model>
  vModelRadio,     // <input type="radio" v-model>
  vModelSelect,    // <select v-model>
  vModelDynamic,   // 動(dòng)態(tài)類型的 v-model(根據(jù) input type 自動(dòng)選擇實(shí)現(xiàn))
  vShow,           // v-show
  vOn,             // v-on 事件監(jiān)聽(tīng)
  vBind,           // v-bind
  withDirectives,  // 應(yīng)用自定義指令
} from '@vue/runtime-dom'

// 在 render function 中手動(dòng)使用 v-model
import { h, withDirectives, vModelText } from 'vue'

export default {
  setup() {
    const text = ref('')
    return () => withDirectives(
      h('input', { 'onUpdate:modelValue': val => (text.value = val) }),
      [[vModelText, text.value]]
    )
  }
}

4.2 CSS 過(guò)渡鉤子(內(nèi)部實(shí)現(xiàn))

import { Transition, TransitionGroup } from '@vue/runtime-dom'

// TransitionGroup 配置詳解(文檔常被忽視的屬性)
h(TransitionGroup, {
  name: 'list',
  tag: 'ul',           // 渲染的包裝元素(默認(rèn) span)
  moveClass: 'move',   // FLIP 動(dòng)畫時(shí)的 CSS 類名
  appear: true,        // 初次渲染也觸發(fā)過(guò)渡
  css: false,          // 禁用 CSS 過(guò)渡,純 JS 控制
  onBeforeEnter(el) {},
  onEnter(el, done) { /* 必須調(diào)用 done() */ },
  onLeave(el, done) { /* 必須調(diào)用 done() */ },
})

4.3 SSR 相關(guān)

import { createSSRApp } from '@vue/runtime-dom'

// SSR hydration:將服務(wù)端渲染的 HTML 與 Vue 狀態(tài)綁定
const app = createSSRApp(App)
app.mount('#app') // 自動(dòng)檢測(cè)已有 HTML,進(jìn)行 hydration 而非全量渲染

五、@vue/compiler-core:編譯器核心

這是 Vue 模板編譯管道的核心,純函數(shù)式架構(gòu),完全平臺(tái)無(wú)關(guān)。

5.1 完整編譯管道

模板字符串
    ↓
parse()          → AST(抽象語(yǔ)法樹(shù))
    ↓
transform()      → 轉(zhuǎn)換 AST(應(yīng)用各種 transform 插件)
    ↓
generate()       → 渲染函數(shù)代碼字符串
import { parse, transform, generate, baseParse } from '@vue/compiler-core'

// 解析模板為 AST
const ast = parse('<div>{{ msg }}</div>')

// 對(duì) AST 進(jìn)行轉(zhuǎn)換(插件化)
transform(ast, {
  nodeTransforms: [
    // 自定義 transform 插件
    (node, context) => {
      if (node.type === 1 /* ELEMENT */ && node.tag === 'div') {
        // 可以修改 AST,添加、刪除、替換節(jié)點(diǎn)
      }
    }
  ]
})

// 生成代碼
const { code } = generate(ast)
console.log(code) // 輸出渲染函數(shù)字符串

5.2 AST 節(jié)點(diǎn)類型(NodeTypes枚舉)

import { NodeTypes } from '@vue/compiler-core'

// 完整節(jié)點(diǎn)類型列表(調(diào)試 AST 時(shí)極為有用)
NodeTypes.ROOT           // 0 - 根節(jié)點(diǎn)
NodeTypes.ELEMENT        // 1 - 元素節(jié)點(diǎn)
NodeTypes.TEXT           // 2 - 文本節(jié)點(diǎn)
NodeTypes.COMMENT        // 3 - 注釋節(jié)點(diǎn)
NodeTypes.SIMPLE_EXPRESSION // 4 - 簡(jiǎn)單表達(dá)式(如 msg、count + 1)
NodeTypes.INTERPOLATION  // 5 - 插值({{ }})
NodeTypes.ATTRIBUTE      // 6 - 普通屬性
NodeTypes.DIRECTIVE      // 7 - 指令(v-if、v-for 等)
NodeTypes.COMPOUND_EXPRESSION // 8 - 復(fù)合表達(dá)式
NodeTypes.IF             // 9 - v-if 結(jié)構(gòu)
NodeTypes.IF_BRANCH      // 10 - v-if 分支
NodeTypes.FOR            // 11 - v-for 結(jié)構(gòu)
NodeTypes.TEXT_CALL      // 12
NodeTypes.VNODE_CALL     // 13 - createVNode 調(diào)用
NodeTypes.JS_CALL_EXPRESSION     // 14
NodeTypes.JS_OBJECT_EXPRESSION   // 15
NodeTypes.JS_PROPERTY            // 16
NodeTypes.JS_ARRAY_EXPRESSION    // 17
NodeTypes.JS_FUNCTION_EXPRESSION // 18
NodeTypes.JS_CONDITIONAL_EXPRESSION // 19
NodeTypes.JS_CACHE_EXPRESSION    // 20 - 帶緩存的表達(dá)式(v-once / 靜態(tài)提升)

5.3 編譯優(yōu)化標(biāo)記(PatchFlags)

這是 Vue 3 性能優(yōu)化的核心機(jī)制,編譯器通過(guò)這些標(biāo)記讓運(yùn)行時(shí)的 diff 算法跳過(guò)靜態(tài)內(nèi)容:

import { PatchFlags } from '@vue/compiler-core'

PatchFlags.TEXT          // 1  - 動(dòng)態(tài)文本內(nèi)容
PatchFlags.CLASS         // 2  - 動(dòng)態(tài) class
PatchFlags.STYLE         // 4  - 動(dòng)態(tài) style
PatchFlags.PROPS         // 8  - 動(dòng)態(tài) props(非 class/style)
PatchFlags.FULL_PROPS    // 16 - 有動(dòng)態(tài)鍵名的 props(如 v-bind="obj")
PatchFlags.HYDRATE_EVENTS // 32 - 含事件監(jiān)聽(tīng)的節(jié)點(diǎn)(SSR hydration 用)
PatchFlags.STABLE_FRAGMENT // 64 - 子節(jié)點(diǎn)順序穩(wěn)定的 Fragment
PatchFlags.KEYED_FRAGMENT  // 128 - 帶 key 的 Fragment
PatchFlags.UNKEYED_FRAGMENT // 256 - 無(wú) key 的 Fragment(v-for 無(wú) key 時(shí))
PatchFlags.NEED_PATCH    // 512 - 需要 patch 但不在上述分類中
PatchFlags.DYNAMIC_SLOTS // 1024 - 動(dòng)態(tài)插槽
PatchFlags.DEV_ROOT_FRAGMENT // 2048 - dev 模式根節(jié)點(diǎn) Fragment
PatchFlags.HOISTED       // -1  - 靜態(tài)提升節(jié)點(diǎn),永不更新
PatchFlags.BAIL          // -2  - 退出優(yōu)化,進(jìn)行完整 diff

理解 PatchFlags 是分析 Vue 模板編譯產(chǎn)物、進(jìn)行極致性能優(yōu)化的必備知識(shí)。

5.4ShapeFlags(組件形態(tài)標(biāo)記)

import { ShapeFlags } from '@vue/shared' // 實(shí)際在 shared 包中

ShapeFlags.ELEMENT                    // 1   - 普通 DOM 元素
ShapeFlags.FUNCTIONAL_COMPONENT       // 2   - 函數(shù)式組件
ShapeFlags.STATEFUL_COMPONENT         // 4   - 有狀態(tài)組件
ShapeFlags.TEXT_CHILDREN              // 8   - children 是文本
ShapeFlags.ARRAY_CHILDREN             // 16  - children 是數(shù)組
ShapeFlags.SLOTS_CHILDREN             // 32  - children 是插槽對(duì)象
ShapeFlags.TELEPORT                   // 64  - Teleport 組件
ShapeFlags.SUSPENSE                   // 128 - Suspense 組件
ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE // 256
ShapeFlags.COMPONENT_KEPT_ALIVE       // 512
ShapeFlags.COMPONENT                  // 6   - FUNCTIONAL | STATEFUL 的組合

5.5 自定義編譯器插件

import { parse, transform, generate, createTransformContext } from '@vue/compiler-core'

// 實(shí)現(xiàn)一個(gè)自定義 transform:自動(dòng)給所有 div 添加 data-testid
const myTransform = (node, context) => {
  if (node.type === 1 && node.tag === 'div') {
    node.props.push({
      type: 6, // NodeTypes.ATTRIBUTE
      name: 'data-testid',
      value: { type: 2, content: 'auto-id' }
    })
  }
}

const ast = parse('<div><span>hello</span></div>')
transform(ast, { nodeTransforms: [myTransform] })
const { code } = generate(ast, { mode: 'module' })

六、@vue/compiler-dom:瀏覽器編譯器

compiler-core 基礎(chǔ)上擴(kuò)展了瀏覽器專屬的處理邏輯。

6.1@vue/compiler-domvs@vue/compiler-core

能力compiler-corecompiler-dom
模板解析??(擴(kuò)展 HTML 實(shí)體)
v-if / v-for??
v-model基礎(chǔ)實(shí)現(xiàn)?(區(qū)分 input/select/checkbox)
v-on基礎(chǔ)實(shí)現(xiàn)?(支持 .stop .prevent 等修飾符)
靜態(tài)提升??
內(nèi)聯(lián)事件緩存??
SSR 優(yōu)化??

6.2compile函數(shù)

import { compile } from '@vue/compiler-dom'

// 直接將模板字符串編譯為渲染函數(shù)代碼
const { code } = compile('<div>{{ msg }}</div>', {
  mode: 'module',           // 'module' | 'function'
  prefixIdentifiers: true,  // 是否給變量名加前綴
  hoistStatic: true,        // 靜態(tài)節(jié)點(diǎn)提升
  cacheHandlers: true,      // 內(nèi)聯(lián)事件處理器緩存
  ssr: false,               // 是否生成 SSR 渲染代碼
  ssrCssVars: '',           // SSR CSS 變量
  isNativeTag: (tag) => true, // 判斷是否是原生 HTML 標(biāo)簽
  isCustomElement: (tag) => tag.includes('-'), // 自定義元素判斷
  
  // 編譯時(shí)優(yōu)化選項(xiàng)
  scopeId: 'data-v-xxxxxx', // Scoped CSS 的 scope ID(SFC 場(chǎng)景)
})

console.log(code)
// import { toDisplayString as _toDisplayString, ... } from "vue"
// export function render(_ctx, _cache) {
//   return (_openBlock(), _createElementBlock("div", null, _toDisplayString(_ctx.msg), ...))
// }

七、@vue/shared:內(nèi)部工具函數(shù)

這個(gè)包雖然標(biāo)注為"內(nèi)部使用",但其中有不少工具函數(shù)在框架級(jí)開(kāi)發(fā)中很有價(jià)值。

import {
  EMPTY_OBJ,       // Object.freeze({}) — 空對(duì)象常量
  EMPTY_ARR,       // Object.freeze([]) — 空數(shù)組常量
  NOOP,            // () => {} — 空操作函數(shù)
  NO,              // () => false
  
  isArray,         // Array.isArray
  isMap,           // 判斷是否為 Map
  isSet,           // 判斷是否為 Set
  isDate,          // 判斷是否為 Date
  isRegExp,        // 判斷是否為 RegExp
  isFunction,      // typeof val === 'function'
  isString,        // typeof val === 'string'
  isSymbol,        // typeof val === 'symbol'
  isObject,        // val !== null && typeof val === 'object'
  isPromise,       // isObject(val) && isFunction(val.then)
  isPlainObject,   // Object.prototype.toString.call(val) === '[object Object]'
  
  extend,          // Object.assign
  hasOwn,          // Object.prototype.hasOwnProperty.call
  camelize,        // kebab-case → camelCase('on-click' → 'onClick')
  capitalize,      // 首字母大寫
  hyphenate,       // camelCase → kebab-case(與 camelize 互逆)
  toHandlerKey,    // 'click' → 'onClick'
  
  looseEqual,      // 寬松相等比較(數(shù)組、對(duì)象深比較,用于 v-model 多選場(chǎng)景)
  looseIndexOf,    // 使用 looseEqual 的 indexOf
  
  invokeArrayFns,  // 批量調(diào)用函數(shù)數(shù)組(生命周期鉤子的內(nèi)部調(diào)用方式)
  def,             // Object.defineProperty 封裝
  toRawType,       // Object.prototype.toString 取類型名('Map', 'Set', 'Array' 等)
  makeMap,         // 從字符串創(chuàng)建成員檢測(cè)函數(shù)(HTML 標(biāo)簽白名單等場(chǎng)景)
} from '@vue/shared'

// makeMap 示例:
const isHTMLTag = makeMap('div,span,p,a,img,ul,li,...')
isHTMLTag('div')  // true
isHTMLTag('my-comp') // false

八、完整包導(dǎo)出結(jié)構(gòu)總覽

Vue 3 包生態(tài)
│
├── @vue/reactivity(獨(dú)立響應(yīng)式)
│   ├── 核心:ref, reactive, computed, watch
│   ├── 淺層:shallowRef, shallowReactive, shallowReadonly
│   ├── 副作用:effect, effectScope, getCurrentScope, onScopeDispose
│   ├── 追蹤控制:pauseTracking, resumeTracking, resetTracking
│   ├── 工具:toRaw, markRaw, proxyRefs, triggerRef, customRef
│   ├── 類型判斷:isRef, isReactive, isReadonly, isProxy, isShallow
│   └── 轉(zhuǎn)換:toRef, toRefs, toValue, unref
│
├── @vue/runtime-core(核心運(yùn)行時(shí))
│   ├── 應(yīng)用:createApp(通過(guò) runtime-dom 暴露)
│   ├── 組件:defineComponent, defineAsyncComponent
│   ├── VNode:h, createVNode, cloneVNode, mergeProps, createTextVNode
│   ├── 編譯助手:openBlock, createBlock, createElementBlock(內(nèi)部)
│   ├── 實(shí)例:getCurrentInstance, useAttrs, useSlots, useCssModule
│   ├── 注入:provide, inject, InjectionKey
│   ├── 生命周期:onMounted...onUnmounted, onRenderTracked, onRenderTriggered
│   ├── 調(diào)度:nextTick, queuePostFlushCb
│   ├── 渲染器:createRenderer, createHydrationRenderer
│   └── 內(nèi)置組件:Suspense, KeepAlive, Teleport(定義在此)
│
├── @vue/runtime-dom(瀏覽器運(yùn)行時(shí))
│   ├── 應(yīng)用:createApp, createSSRApp, render, hydrate
│   ├── 指令實(shí)現(xiàn):vModelText, vModelCheckbox, vShow 等
│   ├── 過(guò)渡:Transition, TransitionGroup
│   └── 重新導(dǎo)出:全部 runtime-core 導(dǎo)出
│
├── @vue/compiler-core(編譯器核心)
│   ├── 編譯管道:parse, transform, generate
│   ├── 枚舉:NodeTypes, PatchFlags, ElementTypes
│   ├── 工具:createTransformContext, traverseNode
│   └── 助手:createSimpleExpression, createCallExpression 等
│
├── @vue/compiler-dom(瀏覽器編譯器)
│   ├── 頂層:compile(模板字符串 → 渲染函數(shù)代碼)
│   └── 重新導(dǎo)出:全部 compiler-core 導(dǎo)出
│
└── @vue/shared(內(nèi)部工具)
    ├── 類型判斷:isArray, isFunction, isObject, isPromise...
    ├── 字符串:camelize, hyphenate, capitalize, toHandlerKey
    ├── 標(biāo)志:ShapeFlags, PatchFlags(部分)
    └── 工具:makeMap, extend, hasOwn, looseEqual, invokeArrayFns

九、架構(gòu)層次與使用建議

適用場(chǎng)景是否可獨(dú)立使用
@vue/reactivity非 UI 的響應(yīng)式狀態(tài)管理? 完全獨(dú)立
@vue/runtime-core自定義渲染器? 需搭配自定義渲染器
@vue/runtime-dom瀏覽器 Vue 應(yīng)用? 等價(jià)于 vue(無(wú)編譯器)
@vue/compiler-core構(gòu)建工具插件、代碼轉(zhuǎn)換? 獨(dú)立使用
@vue/compiler-dom運(yùn)行時(shí)模板編譯(少用)? 獨(dú)立使用
@vue/shared框架級(jí)工具函數(shù)?? 內(nèi)部包,API 隨版本變化
vue標(biāo)準(zhǔn)應(yīng)用開(kāi)發(fā)? 聚合所有能力

十、總結(jié)

Vue 3 的包體系圍繞關(guān)注點(diǎn)分離構(gòu)建:

  • 響應(yīng)式渲染 完全解耦,@vue/reactivity 可獨(dú)立運(yùn)行
  • 平臺(tái)無(wú)關(guān)運(yùn)行時(shí)瀏覽器平臺(tái)實(shí)現(xiàn) 分離,createRenderer 支持跨平臺(tái)
  • 編譯器 同樣分層,compiler-core 可擴(kuò)展用于 Vite 插件、Babel 轉(zhuǎn)換等
  • PatchFlagseffectScope 等低層 API 是框架性能優(yōu)化的真正秘密

理解這套架構(gòu),不僅能寫出更高質(zhì)量的組合函數(shù)和 UI 組件庫(kù),也能在需要時(shí)深入框架層進(jìn)行擴(kuò)展——這是從"會(huì)用 Vue"到"精通 Vue 架構(gòu)"的關(guān)鍵跨越。

到此這篇關(guān)于Vue包之vue各子包究竟導(dǎo)出了什么的文章就介紹到這了,更多相關(guān)vue包導(dǎo)出什么內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue-Router滾動(dòng)行為的具體使用

    Vue-Router滾動(dòng)行為的具體使用

    在 Vue Router 中,你可以使用滾動(dòng)行為來(lái)定義路由切換時(shí)頁(yè)面滾動(dòng)的行為,本文就詳細(xì)的介紹一下Vue-Router滾動(dòng)行為的具體使用,感興趣的可以了解一下
    2023-08-08
  • vue實(shí)現(xiàn)移動(dòng)端返回頂部

    vue實(shí)現(xiàn)移動(dòng)端返回頂部

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)移動(dòng)端返回頂部,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • 深入理解Vuex的作用

    深入理解Vuex的作用

    這篇文章主要介紹了深入理解Vuex的作用,對(duì)Vuex感興趣的同學(xué),可以參考下
    2021-05-05
  • Vue指令指令大全

    Vue指令指令大全

    本文為大家介紹了VUE中內(nèi)置指令包括:v-text,v-html,v-show,v-if,v-else,v-else-if,v-for,v-on,v-bind,v-model,v-pre,v-cloak,v-once
    2019-02-02
  • vue3使用axios并封裝axios請(qǐng)求的詳細(xì)步驟

    vue3使用axios并封裝axios請(qǐng)求的詳細(xì)步驟

    本篇文章分步驟給大家介紹了vue3使用axios并封裝axios請(qǐng)求的詳細(xì)步驟,結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友參考下吧
    2023-06-06
  • 利用vite創(chuàng)建vue3項(xiàng)目的全過(guò)程及一個(gè)小BUG詳解

    利用vite創(chuàng)建vue3項(xiàng)目的全過(guò)程及一個(gè)小BUG詳解

    Vite作為一個(gè)構(gòu)建工具,提供了一種快速的方法來(lái)構(gòu)建Vue應(yīng)用,而Vue3?則是一個(gè)前端框架,提供了強(qiáng)大的功能來(lái)構(gòu)建和管理前端項(xiàng)目,下面這篇文章主要給大家介紹了關(guān)于利用vite創(chuàng)建vue3項(xiàng)目的全過(guò)程及一個(gè)小BUG的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • vue element-ui實(shí)現(xiàn)el-table表格多選以及回顯方式

    vue element-ui實(shí)現(xiàn)el-table表格多選以及回顯方式

    這篇文章主要介紹了vue element-ui實(shí)現(xiàn)el-table表格多選以及回顯方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Vue利用mockjs編寫假數(shù)據(jù)并應(yīng)用的問(wèn)題記錄

    Vue利用mockjs編寫假數(shù)據(jù)并應(yīng)用的問(wèn)題記錄

    這篇文章主要介紹了Vue利用mockjs編寫假數(shù)據(jù)并應(yīng)用,本文通過(guò)實(shí)例代碼給大家詳細(xì)講解,對(duì)Vue?mockjs數(shù)據(jù)相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • Vue監(jiān)聽(tīng)數(shù)據(jù)對(duì)象變化源碼

    Vue監(jiān)聽(tīng)數(shù)據(jù)對(duì)象變化源碼

    這篇文章主要為大家詳細(xì)介紹了Vue監(jiān)聽(tīng)數(shù)據(jù)對(duì)象變化的源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • vue中監(jiān)聽(tīng)scroll事件失效的問(wèn)題及解決

    vue中監(jiān)聽(tīng)scroll事件失效的問(wèn)題及解決

    這篇文章主要介紹了vue中監(jiān)聽(tīng)scroll事件失效的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09

最新評(píng)論

屏东县| 沾益县| 新化县| 江西省| 寿光市| 余姚市| 徐闻县| 东丽区| 登封市| 托里县| 徐州市| 浠水县| 天等县| 旬邑县| 玛沁县| 乐亭县| 永定县| 民县| 张家口市| 崇阳县| 东莞市| 西华县| 孟津县| 宝丰县| 江阴市| 徐水县| 布尔津县| 明水县| 彩票| 温泉县| 小金县| 楚雄市| 郁南县| 余干县| 上犹县| 岢岚县| 福贡县| 新宁县| 北票市| 晋宁县| 泰安市|