wip(compiler): adjust renderSlot() signature

This commit is contained in:
Evan You
2019-10-03 14:29:12 -04:00
parent 306c22efe1
commit 05db2a9c6c
9 changed files with 83 additions and 67 deletions

View File

@@ -1,12 +1,11 @@
import { NodeTransform } from '../transform'
import {
NodeTypes,
CompoundExpressionNode,
createCompoundExpression,
CallExpression,
createCallExpression
createCallExpression,
ExpressionNode
} from '../ast'
import { isSimpleIdentifier, isSlotOutlet } from '../utils'
import { isSlotOutlet } from '../utils'
import { buildProps } from './transformElement'
import { createCompilerError, ErrorCodes } from '../errors'
import { RENDER_SLOT } from '../runtimeConstants'
@@ -15,7 +14,7 @@ export const transformSlotOutlet: NodeTransform = (node, context) => {
if (isSlotOutlet(node)) {
const { props, children, loc } = node
const $slots = context.prefixIdentifiers ? `_ctx.$slots` : `$slots`
let slot: string | CompoundExpressionNode = $slots + `.default`
let slotName: string | ExpressionNode = `"default"`
// check for <slot name="xxx" OR :name="xxx" />
let nameIndex: number = -1
@@ -24,11 +23,7 @@ export const transformSlotOutlet: NodeTransform = (node, context) => {
if (prop.type === NodeTypes.ATTRIBUTE) {
if (prop.name === `name` && prop.value) {
// static name="xxx"
const name = prop.value.content
const accessor = isSimpleIdentifier(name)
? `.${name}`
: `[${JSON.stringify(name)}]`
slot = `${$slots}${accessor}`
slotName = JSON.stringify(prop.value.content)
nameIndex = i
break
}
@@ -42,20 +37,14 @@ export const transformSlotOutlet: NodeTransform = (node, context) => {
arg.content === `name`
) {
// dynamic :name="xxx"
slot = createCompoundExpression([
$slots + `[`,
...(exp.type === NodeTypes.SIMPLE_EXPRESSION
? [exp]
: exp.children),
`]`
])
slotName = exp
nameIndex = i
break
}
}
}
const slotArgs: CallExpression['arguments'] = [slot]
const slotArgs: CallExpression['arguments'] = [$slots, slotName]
const propsWithoutName =
nameIndex > -1
? props.slice(0, nameIndex).concat(props.slice(nameIndex + 1))

View File

@@ -118,11 +118,12 @@ export const transformFor = createStructuralDirectiveTransform(
if (isTemplate && keyProperty) {
// <template v-for="..." :key="..."><slot/></template>
// we need to inject the key to the renderSlot() call.
const existingProps = childBlock.arguments[1] as
// the props for renderSlot is passed as the 3rd argument.
const existingProps = childBlock.arguments[2] as
| PropsExpression
| undefined
| 'null'
childBlock.arguments[1] = injectProp(
childBlock.arguments[2] = injectProp(
existingProps,
keyProperty,
context

View File

@@ -27,7 +27,8 @@ import {
EMPTY,
FRAGMENT,
APPLY_DIRECTIVES,
CREATE_VNODE
CREATE_VNODE,
RENDER_SLOT
} from '../runtimeConstants'
import { injectProp } from '../utils'
import { PropsExpression } from './transformElement'
@@ -185,18 +186,24 @@ function createChildrenCodegenNode(
vnodeCall = vnodeCall.arguments[0] as CallExpression
}
// Change createVNode to createBlock.
// It's possible to have renderSlot() here as well - which already produces
// a block, so no need to change the callee. renderSlot() also accepts props
// as the 2nd argument, so the key injection logic below works for it too.
if (vnodeCall.callee.includes(CREATE_VNODE)) {
vnodeCall.callee = helper(CREATE_BLOCK)
}
// It's possible to have renderSlot() here as well - which already produces
// a block, so no need to change the callee. However it accepts props at
// a different arg index so make sure to check for so that the key injection
// logic below works for it too.
const propsIndex = vnodeCall.callee.includes(RENDER_SLOT) ? 2 : 1
// inject branch key
const existingProps = vnodeCall.arguments[1] as
const existingProps = vnodeCall.arguments[propsIndex] as
| PropsExpression
| undefined
| 'null'
vnodeCall.arguments[1] = injectProp(existingProps, keyProperty, context)
vnodeCall.arguments[propsIndex] = injectProp(
existingProps,
keyProperty,
context
)
return childCodegen
}
}