家喻户晓,在
vue3
中v-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>
发表回复