diff --git a/packages/uni-template-compiler/__tests__/compiler-extra.spec.js b/packages/uni-template-compiler/__tests__/compiler-extra.spec.js index 9b006af0733ff0cec35480063fdb41fe1d4a9bdd..73343bfaeafc40280967fb5e92fa2db17b12d16e 100644 --- a/packages/uni-template-compiler/__tests__/compiler-extra.spec.js +++ b/packages/uni-template-compiler/__tests__/compiler-extra.spec.js @@ -337,6 +337,11 @@ describe('mp:compiler-extra', () => { '', 'with(this){if(!_isMounted){e0=function($event,item){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],item=_temp2.item;var _temp,_temp2;return $test.test(item,item.length,undefined)}}}' ) + assertCodegen( + '', + '', + 'with(this){if(!_isMounted){e0=(event,item,...args)=>{var _temp=args[args.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],item=_temp2.item;var _temp,_temp2;return showEventInfo(event,item)}}}' + ) }) it('generate class binding', () => { diff --git a/packages/uni-template-compiler/lib/script/traverse/data/event.js b/packages/uni-template-compiler/lib/script/traverse/data/event.js index cfc01a9b7157591ea4914b33fc298ccdb5c3a16a..2cb47a7d39cce93582fe49ea3460e245f0ecb28b 100644 --- a/packages/uni-template-compiler/lib/script/traverse/data/event.js +++ b/packages/uni-template-compiler/lib/script/traverse/data/event.js @@ -202,6 +202,10 @@ function parseEventByCallExpression (callExpr, methods) { methods.push(t.arrayExpression(arrayExpression)) } +function isValuePath (path) { + return path.key !== 'key' && path.key !== 'id' && (path.key !== 'property' || path.parent.computed) && !(path.key === 'value' && path.parentPath.parentPath.isObjectPattern()) && !(path.key === 'left' && path.parentPath.parentPath.parentPath.isObjectPattern()) +} + function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, tagName, ret) { const key = keyPath.node let type = key.value || key.name || '' @@ -268,18 +272,31 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, state.errors.add( `${tagName} 组件 ${type} 事件仅支持 @${type}="methodName" 方式绑定` ) - } else if (funcPath.isArrowFunctionExpression()) { // e=>count++ - methods.push(addEventExpressionStatement(funcPath, state, isCustom)) } else { let anonymous = true // "click":function($event) {click1(item);click2(item);} const body = funcPath.node.body && funcPath.node.body.body - if (body && body.length) { + const funcParams = funcPath.node.params + if (body && body.length && funcParams && funcParams.length === 1) { const exprStatements = body.filter(node => { return t.isExpressionStatement(node) && t.isCallExpression(node.expression) }) if (exprStatements.length === body.length) { + const paramPath = funcPath.get('params')[0] + const paramName = paramPath.node.name + if (paramName !== '$event') { + funcPath.get('body').traverse({ + Identifier (path) { + const node = path.node + const binding = path.scope.getBinding(node.name) + if (binding && binding.identifier === paramPath.node && isValuePath(path)) { + path.replaceWith(t.identifier('$event')) + } + } + }) + paramPath.replaceWith(t.identifier('$event')) + } anonymous = false exprStatements.forEach(exprStatement => { parseEventByCallExpression(exprStatement.expression, methods) @@ -335,7 +352,7 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, const scope = path.scope const node = path.node const name = node.name - if (path.key !== 'key' && (path.key !== 'property' || path.parent.computed) && scope && !scope.hasOwnBinding(name) && scope.hasBinding(name) && !params.includes(name) && name !== 'undefined') { + if (isValuePath(path) && scope && !scope.hasOwnBinding(name) && scope.hasBinding(name) && !params.includes(name) && name !== 'undefined') { params.push(name) } } @@ -344,10 +361,15 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, funcPath.node.params.push(t.identifier(name)) }) if (params.length) { + let argumentsName = 'arguments' + if (funcPath.isArrowFunctionExpression()) { + argumentsName = 'args' + funcPath.node.params.push(t.restElement(t.identifier(argumentsName))) + } const datasetUid = funcPath.scope.generateDeclaredUidIdentifier().name const paramsUid = funcPath.scope.generateDeclaredUidIdentifier().name const dataset = ATTR_DATA_EVENT_PARAMS.substring(5) - const code = `var ${datasetUid}=arguments[arguments.length-1].currentTarget.dataset,${paramsUid}=${datasetUid}.${dataset.replace(/-([a-z])/, (_, str) => str.toUpperCase())}||${datasetUid}['${dataset}'],${params.map(item => `${item}=${paramsUid}.${item}`).join(',')}` + const code = `var ${datasetUid}=${argumentsName}[${argumentsName}.length-1].currentTarget.dataset,${paramsUid}=${datasetUid}.${dataset.replace(/-([a-z])/, (_, str) => str.toUpperCase())}||${datasetUid}['${dataset}'],${params.map(item => `${item}=${paramsUid}.${item}`).join(',')}` funcPath.node.body.body.unshift(parser.parse(code).program.body[0]) } methods.push(addEventExpressionStatement(funcPath, state, isComponent, isNativeOn))