关于vue.js:vue3-模板编译-我竟把-vif-和-vfor-的优先级改回来了不信你看-🤣

家喻户晓,在 vue3v-if 总是优先于 v-for 失效

然而,在某些状况下,咱们可能更心愿 v-for 的优先级更高,以便在渲染组件之前先遍历数据列表。

尽管 vue3 并没有提供间接批改指令优先级的办法,然而咱们能够应用 AST(形象语法树) 转换来实现这一点。

🌈 在线演示

📄 vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { transformForIf } from './transformForIf'

export default defineConfig({
  plugins: [
    vue({
      template: { compilerOptions: { nodeTransforms: [transformForIf] } }
    })
  ]
})

📄 transformForIf.ts

import { remove } from '@vue/shared'
import { NodeTransform, findDir, findProp } from '@vue/compiler-core'

const ELEMENT = 1

// 创立 template 节点
export const createTemplateNode = (props: BaseElementNode['props'], children: BaseElementNode['children'], loc: BaseElementNode['loc']): TemplateNode => ({
  type: ELEMENT,
  tagType: TEMPLATE,
  tag: 'template',
  props: props.filter(e => e),
  children,
  codegenNode: undefined,
  ns: 0,
  isSelfClosing: false,
  loc
})

export const transformForIf: NodeTransform = node => {
  if (node.type != ELEMENT) return

  node.children.forEach((child, i) => {
    if (child.type != ELEMENT) return

    const VFor = findDir(child, 'for')
    if (!VFor) return

    const VIf = findDir(child, 'if')
    if (!VIf) return

    const key = findProp(child, 'key')

    remove(child.props, VFor)
    remove(child.props, VIf)
    remove(child.props, key)

    const templateIf = createTemplateNode([VIf], [child], VIf.loc)
    const templateFor = createTemplateNode([VFor, key], [templateIf], VFor.loc)

    node.children[i] = templateFor
  })
}

🔺 以上就是残缺代码了


🎃 让咱们来试试成果

<template>
  <div>
    <span v-for="i in 10" v-if="i % 2">{{ i }}</span>
  </div>
</template>

🚀 运行胜利 😆

🚀 在线 StackBlitz 编辑


👍 点个赞吧 ✨ 👈

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理