feat(compile-core): handle falsy dynamic args for v-on and v-bind (#2393)

fix #2388
This commit is contained in:
ᴜɴвʏтᴇ
2020-10-20 05:15:53 +08:00
committed by GitHub
parent 7390487c7d
commit 052a621762
15 changed files with 96 additions and 71 deletions

View File

@@ -71,7 +71,7 @@ describe('compiler: transform v-bind', () => {
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `id`,
content: `id || ""`,
isStatic: false
},
value: {
@@ -130,7 +130,7 @@ describe('compiler: transform v-bind', () => {
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `_${helperNameMap[CAMELIZE]}(foo)`,
content: `_${helperNameMap[CAMELIZE]}(foo || "")`,
isStatic: false
},
value: {
@@ -149,10 +149,12 @@ describe('compiler: transform v-bind', () => {
key: {
children: [
`_${helperNameMap[CAMELIZE]}(`,
`(`,
{ content: `_ctx.foo` },
`(`,
{ content: `_ctx.bar` },
`)`,
`) || ""`,
`)`
]
},

View File

@@ -1,14 +1,14 @@
import {
baseParse as parse,
transform,
ElementNode,
ObjectExpression,
CompilerOptions,
ElementNode,
ErrorCodes,
NodeTypes,
VNodeCall,
TO_HANDLER_KEY,
helperNameMap,
CAPITALIZE
NodeTypes,
ObjectExpression,
transform,
VNodeCall
} from '../../src'
import { transformOn } from '../../src/transforms/vOn'
import { transformElement } from '../../src/transforms/transformElement'
@@ -76,7 +76,7 @@ describe('compiler: transform v-on', () => {
key: {
type: NodeTypes.COMPOUND_EXPRESSION,
children: [
`"on" + _${helperNameMap[CAPITALIZE]}(`,
`_${helperNameMap[TO_HANDLER_KEY]}(`,
{ content: `event` },
`)`
]
@@ -101,7 +101,7 @@ describe('compiler: transform v-on', () => {
key: {
type: NodeTypes.COMPOUND_EXPRESSION,
children: [
`"on" + _${helperNameMap[CAPITALIZE]}(`,
`_${helperNameMap[TO_HANDLER_KEY]}(`,
{ content: `_ctx.event` },
`)`
]
@@ -126,7 +126,7 @@ describe('compiler: transform v-on', () => {
key: {
type: NodeTypes.COMPOUND_EXPRESSION,
children: [
`"on" + _${helperNameMap[CAPITALIZE]}(`,
`_${helperNameMap[TO_HANDLER_KEY]}(`,
{ content: `_ctx.event` },
`(`,
{ content: `_ctx.foo` },

View File

@@ -23,6 +23,7 @@ export const MERGE_PROPS = Symbol(__DEV__ ? `mergeProps` : ``)
export const TO_HANDLERS = Symbol(__DEV__ ? `toHandlers` : ``)
export const CAMELIZE = Symbol(__DEV__ ? `camelize` : ``)
export const CAPITALIZE = Symbol(__DEV__ ? `capitalize` : ``)
export const TO_HANDLER_KEY = Symbol(__DEV__ ? `toHandlerKey` : ``)
export const SET_BLOCK_TRACKING = Symbol(__DEV__ ? `setBlockTracking` : ``)
export const PUSH_SCOPE_ID = Symbol(__DEV__ ? `pushScopeId` : ``)
export const POP_SCOPE_ID = Symbol(__DEV__ ? `popScopeId` : ``)
@@ -56,6 +57,7 @@ export const helperNameMap: any = {
[TO_HANDLERS]: `toHandlers`,
[CAMELIZE]: `camelize`,
[CAPITALIZE]: `capitalize`,
[TO_HANDLER_KEY]: `toHandlerKey`,
[SET_BLOCK_TRACKING]: `setBlockTracking`,
[PUSH_SCOPE_ID]: `pushScopeId`,
[POP_SCOPE_ID]: `popScopeId`,

View File

@@ -10,6 +10,14 @@ import { CAMELIZE } from '../runtimeHelpers'
export const transformBind: DirectiveTransform = (dir, node, context) => {
const { exp, modifiers, loc } = dir
const arg = dir.arg!
if (arg.type !== NodeTypes.SIMPLE_EXPRESSION) {
arg.children.unshift(`(`)
arg.children.push(`) || ""`)
} else if (!arg.isStatic) {
arg.content = `${arg.content} || ""`
}
// .prop is no longer necessary due to new patch behavior
// .sync is replaced by v-model:arg
if (modifiers.includes('camel')) {

View File

@@ -1,20 +1,20 @@
import { DirectiveTransform, DirectiveTransformResult } from '../transform'
import {
DirectiveNode,
createCompoundExpression,
createObjectProperty,
createSimpleExpression,
DirectiveNode,
ElementTypes,
ExpressionNode,
NodeTypes,
createCompoundExpression,
SimpleExpressionNode,
ElementTypes
SimpleExpressionNode
} from '../ast'
import { capitalize, camelize } from '@vue/shared'
import { camelize, toHandlerKey } from '@vue/shared'
import { createCompilerError, ErrorCodes } from '../errors'
import { processExpression } from './transformExpression'
import { validateBrowserExpression } from '../validateExpression'
import { isMemberExpression, hasScopeRef } from '../utils'
import { CAPITALIZE } from '../runtimeHelpers'
import { hasScopeRef, isMemberExpression } from '../utils'
import { TO_HANDLER_KEY } from '../runtimeHelpers'
const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^\s*function(?:\s+[\w$]+)?\s*\(/
@@ -43,11 +43,15 @@ export const transformOn: DirectiveTransform = (
if (arg.isStatic) {
const rawName = arg.content
// for all event listeners, auto convert it to camelCase. See issue #2249
const normalizedName = capitalize(camelize(rawName))
eventName = createSimpleExpression(`on${normalizedName}`, true, arg.loc)
eventName = createSimpleExpression(
toHandlerKey(camelize(rawName)),
true,
arg.loc
)
} else {
// #2388
eventName = createCompoundExpression([
`"on" + ${context.helperString(CAPITALIZE)}(`,
`${context.helperString(TO_HANDLER_KEY)}(`,
arg,
`)`
])
@@ -55,7 +59,7 @@ export const transformOn: DirectiveTransform = (
} else {
// already a compound expression.
eventName = arg
eventName.children.unshift(`"on" + ${context.helperString(CAPITALIZE)}(`)
eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`)
eventName.children.push(`)`)
}