diff --git a/flow/compiler.js b/flow/compiler.js index 21f70d046d..1716c08bc8 100644 --- a/flow/compiler.js +++ b/flow/compiler.js @@ -56,6 +56,7 @@ declare type ASTIfConditions = Array; declare type ASTElementHandler = { value: string; + params?: Array; modifiers: ?ASTModifiers; }; diff --git a/src/compiler/codegen/events.js b/src/compiler/codegen/events.js index 7bfe5ec1c5..1753a56cde 100644 --- a/src/compiler/codegen/events.js +++ b/src/compiler/codegen/events.js @@ -46,6 +46,17 @@ export function genHandlers ( return res.slice(0, -1) + '}' } +// Generate handler code with binding params on Weex +function genWeexHandler (params: Array, handlerCode: string) { + const wrapperArgs = params.filter(exp => simplePathRE.test(exp) && exp !== '$event') + const handlerParams = wrapperArgs.map(exp => ({ '@binding': exp })) + wrapperArgs.push('$event') + return '{' + + `handler:function(${wrapperArgs.join(',')}){${handlerCode}},\n` + + `params:${JSON.stringify(handlerParams)}` + + '}' +} + function genHandler ( name: string, handler: ASTElementHandler | Array @@ -62,9 +73,14 @@ function genHandler ( const isFunctionExpression = fnExpRE.test(handler.value) if (!handler.modifiers) { - return isMethodPath || isFunctionExpression - ? handler.value - : `function($event){${handler.value}}` // inline statement + if (isMethodPath || isFunctionExpression) { + return handler.value + } + // $flow-disable-line + if (__WEEX__ && handler.params) { + return genWeexHandler(handler.params, handler.value) + } + return `function($event){${handler.value}}` // inline statement } else { let code = '' let genModifierCode = '' @@ -100,6 +116,10 @@ function genHandler ( : isFunctionExpression ? `(${handler.value})($event)` : handler.value + // $flow-disable-line + if (__WEEX__ && handler.params) { + return genWeexHandler(handler.params, code + handlerCode) + } return `function($event){${code}${handlerCode}}` } } diff --git a/src/core/vdom/create-component.js b/src/core/vdom/create-component.js index 991b19e326..3356b2aa24 100644 --- a/src/core/vdom/create-component.js +++ b/src/core/vdom/create-component.js @@ -145,11 +145,11 @@ export function createComponent ( data = data || {} // recycle-list optimized render function for extracting cell-slot - // template. This is essentailly inline expanding instead of creating + // template. This is essentially inline expanding instead of creating // an actual instance. // https://github.com/Hanks10100/weex-native-directive/tree/master/component // $flow-disable-line - if (__WEEX__ && data.attrs['@isInRecycleList']) { + if (__WEEX__ && data.attrs && data.attrs['@isInRecycleList']) { const altRender = Ctor.options['@render'] if (altRender) { return altRender.call( diff --git a/src/platforms/weex/compiler/modules/recycle-list/index.js b/src/platforms/weex/compiler/modules/recycle-list/index.js index 323df23ae8..a492e73aae 100644 --- a/src/platforms/weex/compiler/modules/recycle-list/index.js +++ b/src/platforms/weex/compiler/modules/recycle-list/index.js @@ -4,6 +4,7 @@ import { transformText } from './text' import { transformVBind } from './v-bind' import { transformVIf } from './v-if' import { transformVFor } from './v-for' +import { postTransformVOn } from './v-on' let currentRecycleList = null @@ -31,6 +32,7 @@ function postTransformNode (el: ASTElement) { if (el.tag === 'text') { transformText(el) } + postTransformVOn(el) } if (el === currentRecycleList) { currentRecycleList = null diff --git a/src/platforms/weex/compiler/modules/recycle-list/v-on.js b/src/platforms/weex/compiler/modules/recycle-list/v-on.js new file mode 100644 index 0000000000..347d8d3c7c --- /dev/null +++ b/src/platforms/weex/compiler/modules/recycle-list/v-on.js @@ -0,0 +1,25 @@ +/* @flow */ + +const inlineStatementRE = /^\s*([A-Za-z_$0-9\.]+)*\s*\(\s*(([A-Za-z_$0-9\'\"]+)?(\s*,\s*([A-Za-z_$0-9\'\"]+))*)\s*\)$/ + +function parseHandlerParams (handler: ASTElementHandler) { + const res = inlineStatementRE.exec(handler.value) + if (res && res[2]) { + handler.params = res[2].split(/\s*,\s*/) + } +} + +export function postTransformVOn (el: ASTElement) { + const events: ASTElementHandlers | void = el.events + if (!events) { + return + } + for (const name in events) { + const handler: ASTElementHandler | Array = events[name] + if (Array.isArray(handler)) { + handler.map(fn => parseHandlerParams(fn)) + } else { + parseHandlerParams(handler) + } + } +}