feat(compiler-core): support <portal> in template (#203)
This commit is contained in:
parent
37cbd0098d
commit
4547d85a38
@ -6,7 +6,8 @@ import {
|
||||
RESOLVE_DIRECTIVE,
|
||||
APPLY_DIRECTIVES,
|
||||
TO_HANDLERS,
|
||||
helperNameMap
|
||||
helperNameMap,
|
||||
PORTAL
|
||||
} from '../../src/runtimeHelpers'
|
||||
import {
|
||||
CallExpression,
|
||||
@ -255,6 +256,52 @@ describe('compiler: element transform', () => {
|
||||
])
|
||||
})
|
||||
|
||||
test('should handle <portal> element', () => {
|
||||
const { node } = parseWithElementTransform(
|
||||
`<portal target="#foo"><span /></portal>`
|
||||
)
|
||||
expect(node.callee).toBe(CREATE_VNODE)
|
||||
expect(node.arguments).toMatchObject([
|
||||
PORTAL,
|
||||
createObjectMatcher({
|
||||
target: '#foo'
|
||||
}),
|
||||
[
|
||||
{
|
||||
type: NodeTypes.ELEMENT,
|
||||
tag: 'span',
|
||||
codegenNode: {
|
||||
callee: CREATE_VNODE,
|
||||
arguments: [`"span"`]
|
||||
}
|
||||
}
|
||||
]
|
||||
])
|
||||
})
|
||||
|
||||
test('should handle <Portal> element', () => {
|
||||
const { node } = parseWithElementTransform(
|
||||
`<Portal target="#foo"><span /></Portal>`
|
||||
)
|
||||
expect(node.callee).toBe(CREATE_VNODE)
|
||||
expect(node.arguments).toMatchObject([
|
||||
PORTAL,
|
||||
createObjectMatcher({
|
||||
target: '#foo'
|
||||
}),
|
||||
[
|
||||
{
|
||||
type: NodeTypes.ELEMENT,
|
||||
tag: 'span',
|
||||
codegenNode: {
|
||||
callee: CREATE_VNODE,
|
||||
arguments: [`"span"`]
|
||||
}
|
||||
}
|
||||
]
|
||||
])
|
||||
})
|
||||
|
||||
test('error on v-bind with no argument', () => {
|
||||
const onError = jest.fn()
|
||||
parseWithElementTransform(`<div v-bind/>`, { onError })
|
||||
|
@ -49,7 +49,8 @@ export const enum ElementTypes {
|
||||
ELEMENT,
|
||||
COMPONENT,
|
||||
SLOT,
|
||||
TEMPLATE
|
||||
TEMPLATE,
|
||||
PORTAL
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
@ -99,6 +100,7 @@ export type ElementNode =
|
||||
| ComponentNode
|
||||
| SlotOutletNode
|
||||
| TemplateNode
|
||||
| PortalNode
|
||||
|
||||
export interface BaseElementNode extends Node {
|
||||
type: NodeTypes.ELEMENT
|
||||
@ -134,6 +136,11 @@ export interface TemplateNode extends BaseElementNode {
|
||||
| undefined
|
||||
}
|
||||
|
||||
export interface PortalNode extends BaseElementNode {
|
||||
tagType: ElementTypes.PORTAL
|
||||
codegenNode: ElementCodegenNode | undefined
|
||||
}
|
||||
|
||||
export interface TextNode extends Node {
|
||||
type: NodeTypes.TEXT
|
||||
content: string
|
||||
|
@ -445,6 +445,7 @@ function parseTag(
|
||||
|
||||
if (tag === 'slot') tagType = ElementTypes.SLOT
|
||||
else if (tag === 'template') tagType = ElementTypes.TEMPLATE
|
||||
else if (tag === 'portal' || tag === 'Portal') tagType = ElementTypes.PORTAL
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -23,7 +23,8 @@ import {
|
||||
RESOLVE_DIRECTIVE,
|
||||
RESOLVE_COMPONENT,
|
||||
MERGE_PROPS,
|
||||
TO_HANDLERS
|
||||
TO_HANDLERS,
|
||||
PORTAL
|
||||
} from '../runtimeHelpers'
|
||||
import { getInnerRange, isVSlot, toValidAssetId } from '../utils'
|
||||
import { buildSlots } from './vSlot'
|
||||
@ -38,6 +39,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
if (
|
||||
node.tagType === ElementTypes.ELEMENT ||
|
||||
node.tagType === ElementTypes.COMPONENT ||
|
||||
node.tagType === ElementTypes.PORTAL ||
|
||||
// <template> with v-if or v-for are ignored during traversal.
|
||||
// <template> without v-slot should be treated as a normal element.
|
||||
(node.tagType === ElementTypes.TEMPLATE && !node.props.some(isVSlot))
|
||||
@ -46,6 +48,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
// processed and merged.
|
||||
return () => {
|
||||
const isComponent = node.tagType === ElementTypes.COMPONENT
|
||||
const isPortal = node.tagType === ElementTypes.PORTAL
|
||||
let hasProps = node.props.length > 0
|
||||
let patchFlag: number = 0
|
||||
let runtimeDirectives: DirectiveNode[] | undefined
|
||||
@ -57,7 +60,11 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
}
|
||||
|
||||
const args: CallExpression['arguments'] = [
|
||||
isComponent ? toValidAssetId(node.tag, `component`) : `"${node.tag}"`
|
||||
isComponent
|
||||
? toValidAssetId(node.tag, `component`)
|
||||
: isPortal
|
||||
? context.helper(PORTAL)
|
||||
: `"${node.tag}"`
|
||||
]
|
||||
// props
|
||||
if (hasProps) {
|
||||
|
Loading…
Reference in New Issue
Block a user