forked from vuejs/core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtransformSlotOutlet.ts
88 lines (78 loc) · 2.24 KB
/
transformSlotOutlet.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { NodeTransform, TransformContext } from '../transform'
import {
NodeTypes,
CallExpression,
createCallExpression,
ExpressionNode,
SlotOutletNode,
createFunctionExpression
} from '../ast'
import { isSlotOutlet, findProp } from '../utils'
import { buildProps, PropsExpression } from './transformElement'
import { createCompilerError, ErrorCodes } from '../errors'
import { RENDER_SLOT } from '../runtimeHelpers'
export const transformSlotOutlet: NodeTransform = (node, context) => {
if (isSlotOutlet(node)) {
const { children, loc } = node
const { slotName, slotProps } = processSlotOutlet(node, context)
const slotArgs: CallExpression['arguments'] = [
context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
slotName
]
if (slotProps) {
slotArgs.push(slotProps)
}
if (children.length) {
if (!slotProps) {
slotArgs.push(`{}`)
}
slotArgs.push(createFunctionExpression([], children, false, false, loc))
}
node.codegenNode = createCallExpression(
context.helper(RENDER_SLOT),
slotArgs,
loc
)
}
}
interface SlotOutletProcessResult {
slotName: string | ExpressionNode
slotProps: PropsExpression | undefined
}
export function processSlotOutlet(
node: SlotOutletNode,
context: TransformContext
): SlotOutletProcessResult {
let slotName: string | ExpressionNode = `"default"`
let slotProps: PropsExpression | undefined = undefined
// check for <slot name="xxx" OR :name="xxx" />
const name = findProp(node, 'name')
if (name) {
if (name.type === NodeTypes.ATTRIBUTE && name.value) {
// static name
slotName = JSON.stringify(name.value.content)
} else if (name.type === NodeTypes.DIRECTIVE && name.exp) {
// dynamic name
slotName = name.exp
}
}
const propsWithoutName = name
? node.props.filter(p => p !== name)
: node.props
if (propsWithoutName.length > 0) {
const { props, directives } = buildProps(node, context, propsWithoutName)
slotProps = props
if (directives.length) {
context.onError(
createCompilerError(
ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET,
directives[0].loc
)
)
}
}
return {
slotName,
slotProps
}
}