fix(compiler-ssr): fix input w/ v-bind="obj" codegen

This commit is contained in:
Evan You 2020-03-16 18:14:49 -04:00
parent 9eef37fa32
commit 3b40fc56db
4 changed files with 48 additions and 14 deletions

View File

@ -52,6 +52,7 @@ export const enum NodeTypes {
JS_TEMPLATE_LITERAL, JS_TEMPLATE_LITERAL,
JS_IF_STATEMENT, JS_IF_STATEMENT,
JS_ASSIGNMENT_EXPRESSION, JS_ASSIGNMENT_EXPRESSION,
JS_SEQUENCE_EXPRESSION,
JS_RETURN_STATEMENT JS_RETURN_STATEMENT
} }
@ -282,6 +283,7 @@ export type JSChildNode =
| ConditionalExpression | ConditionalExpression
| CacheExpression | CacheExpression
| AssignmentExpression | AssignmentExpression
| SequenceExpression
export interface CallExpression extends Node { export interface CallExpression extends Node {
type: NodeTypes.JS_CALL_EXPRESSION type: NodeTypes.JS_CALL_EXPRESSION
@ -344,6 +346,7 @@ export type SSRCodegenNode =
| IfStatement | IfStatement
| AssignmentExpression | AssignmentExpression
| ReturnStatement | ReturnStatement
| SequenceExpression
export interface BlockStatement extends Node { export interface BlockStatement extends Node {
type: NodeTypes.JS_BLOCK_STATEMENT type: NodeTypes.JS_BLOCK_STATEMENT
@ -368,6 +371,11 @@ export interface AssignmentExpression extends Node {
right: JSChildNode right: JSChildNode
} }
export interface SequenceExpression extends Node {
type: NodeTypes.JS_SEQUENCE_EXPRESSION
expressions: JSChildNode[]
}
export interface ReturnStatement extends Node { export interface ReturnStatement extends Node {
type: NodeTypes.JS_RETURN_STATEMENT type: NodeTypes.JS_RETURN_STATEMENT
returns: TemplateChildNode | TemplateChildNode[] | JSChildNode returns: TemplateChildNode | TemplateChildNode[] | JSChildNode
@ -727,6 +735,16 @@ export function createAssignmentExpression(
} }
} }
export function createSequenceExpression(
expressions: SequenceExpression['expressions']
): SequenceExpression {
return {
type: NodeTypes.JS_SEQUENCE_EXPRESSION,
expressions,
loc: locStub
}
}
export function createReturnStatement( export function createReturnStatement(
returns: ReturnStatement['returns'] returns: ReturnStatement['returns']
): ReturnStatement { ): ReturnStatement {

View File

@ -23,7 +23,8 @@ import {
IfStatement, IfStatement,
AssignmentExpression, AssignmentExpression,
ReturnStatement, ReturnStatement,
VNodeCall VNodeCall,
SequenceExpression
} from './ast' } from './ast'
import { SourceMapGenerator, RawSourceMap } from 'source-map' import { SourceMapGenerator, RawSourceMap } from 'source-map'
import { import {
@ -593,6 +594,9 @@ function genNode(node: CodegenNode | symbol | string, context: CodegenContext) {
case NodeTypes.JS_ASSIGNMENT_EXPRESSION: case NodeTypes.JS_ASSIGNMENT_EXPRESSION:
!__BROWSER__ && genAssignmentExpression(node, context) !__BROWSER__ && genAssignmentExpression(node, context)
break break
case NodeTypes.JS_SEQUENCE_EXPRESSION:
!__BROWSER__ && genSequenceExpression(node, context)
break
case NodeTypes.JS_RETURN_STATEMENT: case NodeTypes.JS_RETURN_STATEMENT:
!__BROWSER__ && genReturnStatement(node, context) !__BROWSER__ && genReturnStatement(node, context)
break break
@ -914,6 +918,15 @@ function genAssignmentExpression(
genNode(node.right, context) genNode(node.right, context)
} }
function genSequenceExpression(
node: SequenceExpression,
context: CodegenContext
) {
context.push(`(`)
genNodeList(node.expressions, context)
context.push(`)`)
}
function genReturnStatement( function genReturnStatement(
{ returns }: ReturnStatement, { returns }: ReturnStatement,
context: CodegenContext context: CodegenContext

View File

@ -118,7 +118,7 @@ describe('ssr: v-model', () => {
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
let _temp0 let _temp0
_push(\`<input\${_ssrRenderAttrs(_temp0 = _ctx.obj, _mergeProps(_temp0, _ssrGetDynamicModelProps(_temp0, _ctx.foo)))}>\`) _push(\`<input\${_ssrRenderAttrs((_temp0 = _ctx.obj, _mergeProps(_temp0, _ssrGetDynamicModelProps(_temp0, _ctx.foo))))}>\`)
}" }"
`) `)
@ -130,7 +130,7 @@ describe('ssr: v-model', () => {
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
let _temp0 let _temp0
_push(\`<input\${_ssrRenderAttrs(_temp0 = _mergeProps({ id: \\"x\\" }, _ctx.obj, { class: \\"y\\" }), _mergeProps(_temp0, _ssrGetDynamicModelProps(_temp0, _ctx.foo)))}>\`) _push(\`<input\${_ssrRenderAttrs((_temp0 = _mergeProps({ id: \\"x\\" }, _ctx.obj, { class: \\"y\\" }), _mergeProps(_temp0, _ssrGetDynamicModelProps(_temp0, _ctx.foo))))}>\`)
}" }"
`) `)
}) })

View File

@ -22,7 +22,8 @@ import {
TextNode, TextNode,
hasDynamicKeyVBind, hasDynamicKeyVBind,
MERGE_PROPS, MERGE_PROPS,
isBindKey isBindKey,
createSequenceExpression
} from '@vue/compiler-dom' } from '@vue/compiler-dom'
import { import {
escapeHtml, escapeHtml,
@ -107,16 +108,18 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
const tempId = `_temp${context.temps++}` const tempId = `_temp${context.temps++}`
const tempExp = createSimpleExpression(tempId, false) const tempExp = createSimpleExpression(tempId, false)
propsExp.arguments = [ propsExp.arguments = [
createAssignmentExpression(tempExp, props), createSequenceExpression([
createCallExpression(context.helper(MERGE_PROPS), [ createAssignmentExpression(tempExp, props),
tempExp, createCallExpression(context.helper(MERGE_PROPS), [
createCallExpression( tempExp,
context.helper(SSR_GET_DYNAMIC_MODEL_PROPS), createCallExpression(
[ context.helper(SSR_GET_DYNAMIC_MODEL_PROPS),
tempExp, // existing props [
vModel.exp! // model tempExp, // existing props
] vModel.exp! // model
) ]
)
])
]) ])
] ]
} }