mirror of https://github.com/vuejs/core.git
wip: add TransformTransition
This commit is contained in:
parent
05d9f53c08
commit
1511d6cd60
|
@ -76,4 +76,5 @@ export {
|
||||||
} from './errors'
|
} from './errors'
|
||||||
export { resolveModifiers } from './transforms/vOn'
|
export { resolveModifiers } from './transforms/vOn'
|
||||||
export { isValidHTMLNesting } from './htmlNesting'
|
export { isValidHTMLNesting } from './htmlNesting'
|
||||||
|
export { postTransformTransition } from './transforms/Transition'
|
||||||
export * from '@vue/compiler-core'
|
export * from '@vue/compiler-core'
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
type CompilerError,
|
||||||
type ComponentNode,
|
type ComponentNode,
|
||||||
ElementTypes,
|
ElementTypes,
|
||||||
type IfBranchNode,
|
type IfBranchNode,
|
||||||
|
@ -15,40 +16,43 @@ export const transformTransition: NodeTransform = (node, context) => {
|
||||||
) {
|
) {
|
||||||
const component = context.isBuiltInComponent(node.tag)
|
const component = context.isBuiltInComponent(node.tag)
|
||||||
if (component === TRANSITION) {
|
if (component === TRANSITION) {
|
||||||
return () => {
|
return postTransformTransition(node, context.onError)
|
||||||
if (!node.children.length) {
|
}
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// warn multiple transition children
|
export function postTransformTransition(
|
||||||
if (hasMultipleChildren(node)) {
|
node: ComponentNode,
|
||||||
context.onError(
|
onError: (error: CompilerError) => void,
|
||||||
createDOMCompilerError(
|
): () => void {
|
||||||
DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN,
|
return () => {
|
||||||
{
|
if (!node.children.length) {
|
||||||
start: node.children[0].loc.start,
|
return
|
||||||
end: node.children[node.children.length - 1].loc.end,
|
}
|
||||||
source: '',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if it's s single child w/ v-show
|
if (hasMultipleChildren(node)) {
|
||||||
// if yes, inject "persisted: true" to the transition props
|
onError(
|
||||||
const child = node.children[0]
|
createDOMCompilerError(DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN, {
|
||||||
if (child.type === NodeTypes.ELEMENT) {
|
start: node.children[0].loc.start,
|
||||||
for (const p of child.props) {
|
end: node.children[node.children.length - 1].loc.end,
|
||||||
if (p.type === NodeTypes.DIRECTIVE && p.name === 'show') {
|
source: '',
|
||||||
node.props.push({
|
}),
|
||||||
type: NodeTypes.ATTRIBUTE,
|
)
|
||||||
name: 'persisted',
|
}
|
||||||
nameLoc: node.loc,
|
|
||||||
value: undefined,
|
// check if it's s single child w/ v-show
|
||||||
loc: node.loc,
|
// if yes, inject "persisted: true" to the transition props
|
||||||
})
|
const child = node.children[0]
|
||||||
}
|
if (child.type === NodeTypes.ELEMENT) {
|
||||||
}
|
for (const p of child.props) {
|
||||||
|
if (p.type === NodeTypes.DIRECTIVE && p.name === 'show') {
|
||||||
|
node.props.push({
|
||||||
|
type: NodeTypes.ATTRIBUTE,
|
||||||
|
name: 'persisted',
|
||||||
|
nameLoc: node.loc,
|
||||||
|
value: undefined,
|
||||||
|
loc: node.loc,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,11 @@ import {
|
||||||
transformText,
|
transformText,
|
||||||
transformVBind,
|
transformVBind,
|
||||||
transformVIf,
|
transformVIf,
|
||||||
|
transformVShow,
|
||||||
transformVSlot,
|
transformVSlot,
|
||||||
} from '@vue/compiler-vapor'
|
} from '@vue/compiler-vapor'
|
||||||
import { expect } from 'vitest'
|
import { transformTransition } from '../../src/transforms/transformTransition'
|
||||||
|
import { DOMErrorCodes } from '@vue/compiler-dom'
|
||||||
|
|
||||||
const compileWithElementTransform = makeCompile({
|
const compileWithElementTransform = makeCompile({
|
||||||
nodeTransforms: [
|
nodeTransforms: [
|
||||||
|
@ -16,9 +18,11 @@ const compileWithElementTransform = makeCompile({
|
||||||
transformElement,
|
transformElement,
|
||||||
transformVSlot,
|
transformVSlot,
|
||||||
transformChildren,
|
transformChildren,
|
||||||
|
transformTransition,
|
||||||
],
|
],
|
||||||
directiveTransforms: {
|
directiveTransforms: {
|
||||||
bind: transformVBind,
|
bind: transformVBind,
|
||||||
|
show: transformVShow,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -52,4 +56,33 @@ describe('compiler: transition', () => {
|
||||||
// should preserve key
|
// should preserve key
|
||||||
expect(code).contains('n0.$key = _ctx.key')
|
expect(code).contains('n0.$key = _ctx.key')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('warns if multiple children', () => {
|
||||||
|
const onError = vi.fn()
|
||||||
|
compileWithElementTransform(
|
||||||
|
`<Transition>
|
||||||
|
<h1>foo</h1>
|
||||||
|
<h2>bar</h2>
|
||||||
|
</Transition>`,
|
||||||
|
{
|
||||||
|
onError,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
expect(onError).toHaveBeenCalled()
|
||||||
|
expect(onError.mock.calls).toMatchObject([
|
||||||
|
[{ code: DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN }],
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('inject persisted when child has v-show', () => {
|
||||||
|
expect(
|
||||||
|
compileWithElementTransform(`
|
||||||
|
<Transition>
|
||||||
|
<div v-show="ok" />
|
||||||
|
</Transition>
|
||||||
|
`).code,
|
||||||
|
).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO more tests
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,13 +1,33 @@
|
||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`compiler: transition > basic 1`] = `
|
exports[`compiler: transition > basic 1`] = `
|
||||||
"import { VaporTransition as _VaporTransition, createComponent as _createComponent, template as _template } from 'vue';
|
"import { VaporTransition as _VaporTransition, applyVShow as _applyVShow, createComponent as _createComponent, template as _template } from 'vue';
|
||||||
const t0 = _template("<h1>foo</h1>")
|
const t0 = _template("<h1>foo</h1>")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n1 = _createComponent(_VaporTransition, { appear: () => ("") }, {
|
const n1 = _createComponent(_VaporTransition, {
|
||||||
|
appear: () => (""),
|
||||||
|
persisted: () => ("")
|
||||||
|
}, {
|
||||||
"default": () => {
|
"default": () => {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
|
_applyVShow(n0, () => (_ctx.show))
|
||||||
|
return n0
|
||||||
|
}
|
||||||
|
}, true)
|
||||||
|
return n1
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler: transition > inject persisted when child has v-show 1`] = `
|
||||||
|
"import { VaporTransition as _VaporTransition, applyVShow as _applyVShow, createComponent as _createComponent, template as _template } from 'vue';
|
||||||
|
const t0 = _template("<div></div>")
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const n1 = _createComponent(_VaporTransition, { persisted: () => ("") }, {
|
||||||
|
"default": () => {
|
||||||
|
const n0 = t0()
|
||||||
|
_applyVShow(n0, () => (_ctx.ok))
|
||||||
return n0
|
return n0
|
||||||
}
|
}
|
||||||
}, true)
|
}, true)
|
||||||
|
|
|
@ -26,6 +26,7 @@ import { transformVFor } from './transforms/vFor'
|
||||||
import { transformComment } from './transforms/transformComment'
|
import { transformComment } from './transforms/transformComment'
|
||||||
import { transformSlotOutlet } from './transforms/transformSlotOutlet'
|
import { transformSlotOutlet } from './transforms/transformSlotOutlet'
|
||||||
import { transformVSlot } from './transforms/vSlot'
|
import { transformVSlot } from './transforms/vSlot'
|
||||||
|
import { transformTransition } from './transforms/transformTransition'
|
||||||
import type { HackOptions } from './ir'
|
import type { HackOptions } from './ir'
|
||||||
|
|
||||||
export { wrapTemplate } from './transforms/utils'
|
export { wrapTemplate } from './transforms/utils'
|
||||||
|
@ -54,6 +55,7 @@ export function compile(
|
||||||
extend({}, resolvedOptions, {
|
extend({}, resolvedOptions, {
|
||||||
nodeTransforms: [
|
nodeTransforms: [
|
||||||
...nodeTransforms,
|
...nodeTransforms,
|
||||||
|
...(__DEV__ ? [transformTransition] : []),
|
||||||
...(options.nodeTransforms || []), // user transforms
|
...(options.nodeTransforms || []), // user transforms
|
||||||
],
|
],
|
||||||
directiveTransforms: extend(
|
directiveTransforms: extend(
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import type { NodeTransform } from '@vue/compiler-vapor'
|
||||||
|
import { ElementTypes, NodeTypes } from '@vue/compiler-core'
|
||||||
|
import { isTransitionTag } from '../utils'
|
||||||
|
import { postTransformTransition } from '@vue/compiler-dom'
|
||||||
|
|
||||||
|
export const transformTransition: NodeTransform = (node, context) => {
|
||||||
|
if (
|
||||||
|
node.type === NodeTypes.ELEMENT &&
|
||||||
|
node.tagType === ElementTypes.COMPONENT
|
||||||
|
) {
|
||||||
|
if (isTransitionTag(node.tag)) {
|
||||||
|
return postTransformTransition(node, context.options.onError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue