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

Vue編譯器中的過(guò)濾器轉(zhuǎn)換機(jī)制(transformFilter)詳解

 更新時(shí)間:2025年11月05日 08:30:56   作者:excel  
本文將詳細(xì)解讀?Vue?兼容模式下的過(guò)濾器編譯邏輯——transformFilter?模塊,它是?Vue?3?為了兼容?Vue?2?模板過(guò)濾器語(yǔ)法而存在的編譯階段轉(zhuǎn)換器,需要的朋友可以參考下

一、背景:為什么需要 transformFilter?

在 Vue 2 中,我們可以寫(xiě)出這樣的模板:

{{ message | capitalize }}

過(guò)濾器(Filter)語(yǔ)法允許開(kāi)發(fā)者在模板中使用管道符(|)對(duì)數(shù)據(jù)進(jìn)行格式化。

但在 Vue 3 中,這個(gè)語(yǔ)法被移除了,因?yàn)樗屇0暹壿嬇c展示層混雜,不利于維護(hù)。

為了讓舊項(xiàng)目平滑遷移到 Vue 3,官方在“兼容模式(compat mode) ”中保留了該特性,而 transformFilter 就是負(fù)責(zé) 在編譯時(shí)| 表達(dá)式“翻譯”為函數(shù)調(diào)用的核心邏輯。

二、入口函數(shù):transformFilter()

export const transformFilter: NodeTransform = (node, context) => {
  if (!isCompatEnabled(CompilerDeprecationTypes.COMPILER_FILTERS, context)) {
    return
  }

  if (node.type === NodeTypes.INTERPOLATION) {
    rewriteFilter(node.content, context)
  } else if (node.type === NodeTypes.ELEMENT) {
    node.props.forEach((prop) => {
      if (
        prop.type === NodeTypes.DIRECTIVE &&
        prop.name !== 'for' &&
        prop.exp
      ) {
        rewriteFilter(prop.exp, context)
      }
    })
  }
}

作用解析:

僅在兼容模式下生效(通過(guò) isCompatEnabled() 判斷)。

對(duì)兩種類(lèi)型的節(jié)點(diǎn)進(jìn)行處理:

  1. 插值表達(dá)式(如 {{ msg | upper }}
  2. 指令表達(dá)式(如 v-bind:title="msg | trim"

每個(gè)匹配到的表達(dá)式都會(huì)交給 rewriteFilter() 進(jìn)行進(jìn)一步分析。

三、遞歸分析:rewriteFilter()

function rewriteFilter(node: ExpressionNode, context: TransformContext) {
  if (node.type === NodeTypes.SIMPLE_EXPRESSION) {
    parseFilter(node, context)
  } else {
    for (let child of node.children) {
      if (typeof child !== 'object') continue
      if (child.type === NodeTypes.SIMPLE_EXPRESSION) {
        parseFilter(child, context)
      } else if (child.type === NodeTypes.COMPOUND_EXPRESSION) {
        rewriteFilter(node, context)
      } else if (child.type === NodeTypes.INTERPOLATION) {
        rewriteFilter(child.content, context)
      }
    }
  }
}

思路講解:

  • 簡(jiǎn)單表達(dá)式(如 msg | upper)直接進(jìn)入下一步解析。
  • 復(fù)合表達(dá)式(如 msg + "!" | wrap)則遞歸展開(kāi)所有子節(jié)點(diǎn),逐層掃描是否存在過(guò)濾器語(yǔ)法。
  • 這種遞歸保證了在任意嵌套層級(jí)的表達(dá)式中都能正確識(shí)別過(guò)濾器。

四、核心邏輯:parseFilter()

function parseFilter(node: SimpleExpressionNode, context: TransformContext) {
  const exp = node.content
  let inSingle = false, inDouble = false, inTemplateString = false
  let inRegex = false
  let curly = 0, square = 0, paren = 0
  let lastFilterIndex = 0
  let expression, filters: string[] = []

  for (let i = 0; i < exp.length; i++) {
    const c = exp.charCodeAt(i)
    ...
    if (c === 0x7c && !curly && !square && !paren) {
      if (expression === undefined) {
        lastFilterIndex = i + 1
        expression = exp.slice(0, i).trim()
      } else {
        pushFilter()
      }
    }
  }

  if (expression === undefined) {
    expression = exp.trim()
  } else if (lastFilterIndex !== 0) {
    pushFilter()
  }

  if (filters.length) {
    for (let f of filters) {
      expression = wrapFilter(expression, f, context)
    }
    node.content = expression
  }
}

關(guān)鍵邏輯說(shuō)明:

狀態(tài)機(jī)掃描
遍歷表達(dá)式的每個(gè)字符,記錄當(dāng)前是否處于:

  • 單引號(hào) '...'
  • 雙引號(hào) "..."
  • 模板字符串 `...`
  • 正則表達(dá)式 /.../
  • 括號(hào)或數(shù)組中
    避免誤把字符串內(nèi)的 | 當(dāng)作過(guò)濾器分隔符。

識(shí)別管道符
當(dāng)遇到頂層 |(非 ||),并且不在任何括號(hào)中時(shí),認(rèn)為是一個(gè)過(guò)濾器的起點(diǎn)。

拆分表達(dá)式與過(guò)濾器
message | capitalize | trim(10) 拆為:

expression = "message"
filters = ["capitalize", "trim(10)"]

重組表達(dá)式
通過(guò) wrapFilter() 將過(guò)濾器按從左到右順序包裝成嵌套調(diào)用:

toValidAssetId('capitalize', 'filter')(
  toValidAssetId('trim', 'filter')(message)
)

五、封裝函數(shù):wrapFilter()

function wrapFilter(exp: string, filter: string, context: TransformContext) {
  context.helper(RESOLVE_FILTER)
  const i = filter.indexOf('(')
  if (i < 0) {
    context.filters!.add(filter)
    return `${toValidAssetId(filter, 'filter')}(${exp})`
  } else {
    const name = filter.slice(0, i)
    const args = filter.slice(i + 1)
    context.filters!.add(name)
    return `${toValidAssetId(name, 'filter')}(${exp}${args !== ')' ? ',' + args : args}`
  }
}

功能說(shuō)明:

  • 檢查過(guò)濾器是否帶參數(shù)(例如 truncate(10))。
  • 調(diào)用 toValidAssetId() 將過(guò)濾器名轉(zhuǎn)為合法標(biāo)識(shí)符。
  • 將原表達(dá)式 exp 作為第一個(gè)參數(shù)注入。
  • 返回新的函數(shù)調(diào)用字符串。

六、對(duì)比:Vue 2 與 Vue 3 的不同

特性Vue 2Vue 3(兼容模式)Vue 3(標(biāo)準(zhǔn)模式)
過(guò)濾器語(yǔ)法支持 ``支持(內(nèi)部轉(zhuǎn)換)
編譯時(shí)行為直接編譯為 _f("filterName")(exp)重寫(xiě)為函數(shù)調(diào)用不處理
性能影響中等低(僅兼容模式觸發(fā))無(wú)

七、實(shí)踐示例

// 輸入模板
{{ message | capitalize | append('!') }}

// 編譯后表達(dá)式
_append(
  _capitalize(message),
  '!'
)

解釋?zhuān)?/strong>
編譯器會(huì)把 | 鏈?zhǔn)秸{(diào)用轉(zhuǎn)換為多層函數(shù)嵌套調(diào)用,保持與 Vue 2 的行為一致。

八、拓展與啟發(fā)

這個(gè)模塊雖然只是為兼容而存在,但它體現(xiàn)了 Vue 編譯器的幾個(gè)關(guān)鍵思想:

  1. 語(yǔ)法兼容通過(guò) AST 轉(zhuǎn)換實(shí)現(xiàn),而非運(yùn)行時(shí)兼容。
  2. 通過(guò)狀態(tài)機(jī)掃描避免誤判字符。
  3. 函數(shù)式封裝(wrapFilter)保持代碼純凈與擴(kuò)展性。

九、潛在問(wèn)題與注意事項(xiàng)

  • 性能開(kāi)銷(xiāo):每個(gè)表達(dá)式都要字符級(jí)掃描,模板過(guò)大會(huì)影響編譯性能。
  • 語(yǔ)法歧義:若表達(dá)式中本身含 |(非過(guò)濾器用途),可能被誤判。
  • 未來(lái)?xiàng)売?/strong>:Vue 3 官方已聲明 filter 將在未來(lái)版本完全移除,開(kāi)發(fā)者應(yīng)盡早改用 計(jì)算屬性或方法替代。

結(jié)語(yǔ):

transformFilter 是 Vue 3 兼容模式中的一個(gè)“橋梁模塊”,它讓舊項(xiàng)目無(wú)需改動(dòng)即可運(yùn)行在新架構(gòu)上,同時(shí)展示了 Vue 編譯器在語(yǔ)法轉(zhuǎn)換上的高靈活性。

以上就是Vue編譯器中的過(guò)濾器轉(zhuǎn)換機(jī)制(transformFilter)詳解的詳細(xì)內(nèi)容,更多關(guān)于Vue過(guò)濾器轉(zhuǎn)換機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

普宁市| 张家界市| 吴旗县| 靖西县| 寿光市| 灵宝市| 黄大仙区| 鄂伦春自治旗| 历史| 曲松县| 同仁县| 开原市| 杭州市| 钟祥市| 娱乐| 盘锦市| 郑州市| 云阳县| 旺苍县| 涞水县| 泸溪县| 和静县| 吉木萨尔县| 滨海县| 偏关县| 如东县| 巴林左旗| 海丰县| 普定县| 丰顺县| 永仁县| 靖州| 蒲城县| 南开区| 新蔡县| 靖边县| 永新县| 内丘县| 大兴区| 岳普湖县| 通山县|