mirror of https://github.com/vuejs/core.git
refactor(compiler-vapor): group directives by same element
This commit is contained in:
parent
0255505b5d
commit
c2c8070207
|
@ -16,6 +16,18 @@ export function render(_ctx) {
|
|||
}"
|
||||
`;
|
||||
|
||||
exports[`compile > custom directive > basic 1`] = `
|
||||
"import { template as _template, children as _children, withDirectives as _withDirectives, resolveDirective("vTest") as _resolveDirective("vTest"), resolveDirective("vHello") as _resolveDirective("vHello") } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_withDirectives(n1, [[_resolveDirective("vTest")], [_resolveDirective("vHello"), void 0, void 0, { world: true }]])
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compile > directives > custom directive > basic 1`] = `
|
||||
"import { template as _template, children as _children, withDirectives as _withDirectives } from 'vue/vapor';
|
||||
|
||||
|
|
|
@ -207,4 +207,11 @@ describe('compile', () => {
|
|||
|
||||
// TODO: add more test for expression parsing (v-on, v-slot, v-for)
|
||||
})
|
||||
|
||||
describe('custom directive', () => {
|
||||
test('basic', () => {
|
||||
const code = compile(`<div v-test v-hello.world />`)
|
||||
expect(code).matchSnapshot()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -281,11 +281,12 @@ export function generate(
|
|||
)
|
||||
}
|
||||
|
||||
for (const oper of ir.operation.filter(
|
||||
const directiveOps = ir.operation.filter(
|
||||
(oper): oper is WithDirectiveIRNode =>
|
||||
oper.type === IRNodeTypes.WITH_DIRECTIVE,
|
||||
)) {
|
||||
genWithDirective(oper, ctx)
|
||||
)
|
||||
for (const directives of groupDirective(directiveOps)) {
|
||||
genWithDirective(directives, ctx)
|
||||
}
|
||||
|
||||
for (const operation of ir.operation) {
|
||||
|
@ -393,3 +394,12 @@ function genOperation(oper: OperationNode, context: CodegenContext) {
|
|||
return checkNever(oper)
|
||||
}
|
||||
}
|
||||
|
||||
function groupDirective(ops: WithDirectiveIRNode[]): WithDirectiveIRNode[][] {
|
||||
const directiveMap: Record<number, WithDirectiveIRNode[]> = {}
|
||||
for (const oper of ops) {
|
||||
if (!directiveMap[oper.element]) directiveMap[oper.element] = []
|
||||
directiveMap[oper.element].push(oper)
|
||||
}
|
||||
return Object.values(directiveMap)
|
||||
}
|
||||
|
|
|
@ -5,24 +5,26 @@ import type { CodegenContext } from '../generate'
|
|||
import type { WithDirectiveIRNode } from '../ir'
|
||||
|
||||
export function genWithDirective(
|
||||
oper: WithDirectiveIRNode,
|
||||
opers: WithDirectiveIRNode[],
|
||||
context: CodegenContext,
|
||||
) {
|
||||
const { push, newline, pushFnCall, pushMulti, vaporHelper, bindingMetadata } =
|
||||
context
|
||||
const { dir, builtin } = oper
|
||||
|
||||
// TODO merge directive for the same node
|
||||
newline()
|
||||
pushFnCall(
|
||||
vaporHelper('withDirectives'),
|
||||
// 1st arg: node
|
||||
`n${oper.element}`,
|
||||
`n${opers[0].element}`,
|
||||
// 2nd arg: directives
|
||||
() => {
|
||||
push('[')
|
||||
// directive
|
||||
pushMulti(['[', ']', ', '], () => {
|
||||
pushMulti(
|
||||
['[', ']', ', '],
|
||||
...opers.map((oper) => () => {
|
||||
push('[')
|
||||
|
||||
const { dir, builtin } = oper
|
||||
if (dir.name === 'show') {
|
||||
push(vaporHelper('vShow'))
|
||||
} else if (builtin) {
|
||||
|
@ -35,6 +37,8 @@ export function genWithDirective(
|
|||
createSimpleExpression(directiveReference)
|
||||
directiveExpression.ast = null
|
||||
genExpression(directiveExpression, context)
|
||||
} else {
|
||||
push(vaporHelper(`resolveDirective("${directiveReference}")`))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,8 +62,10 @@ export function genWithDirective(
|
|||
push(genDirectiveModifiers(dir.modifiers))
|
||||
push(' }')
|
||||
}
|
||||
})
|
||||
|
||||
push(']')
|
||||
}),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue