From 2cb8ea3fee741807a15bf8f3049ab062a7d9508c Mon Sep 17 00:00:00 2001 From: Hanks Date: Mon, 30 Oct 2017 19:28:40 -0500 Subject: [PATCH] feat(weex): support compiling `v-on` in the weex native directive (#6892) * refactor(compiler): move postTransforms to after children are processed * feat(weex): recycle-list support WIP * refactor: fix types * feat(weex): split text into separate module * feat($compiler): supports compiling v-bind to the weex native directive in recycle-list * feat(compile): supports compiling v-if to the weex native directive * feat($compiler): supports compiling v-for to the weex native directive * feat($compiler): compile weex native directives in preTransformNode * feat($compiler): supports compiling v-else-if and v-else to the weex native directive * feat($event): support binding parameters on event handler within weex recycle-list * refactor: mark weex-specific block * feat(wip): recycle list template inline expand * build: add weex factory dev script * feat($compiler): support to compile "v-on" into weex native directive * feat($compiler): adjust handler params to fit the weex native renderer + Filter the non-expression params and the `$event`. + Use `$event` as the last argument of handler. --- flow/compiler.js | 1 + src/compiler/codegen/events.js | 26 ++++++++++++++++--- src/core/vdom/create-component.js | 4 +-- .../compiler/modules/recycle-list/index.js | 2 ++ .../compiler/modules/recycle-list/v-on.js | 25 ++++++++++++++++++ 5 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 src/platforms/weex/compiler/modules/recycle-list/v-on.js diff --git a/flow/compiler.js b/flow/compiler.js index 21f70d04..1716c08b 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 7bfe5ec1..1753a56c 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 991b19e3..3356b2aa 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 323df23a..a492e73a 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 00000000..347d8d3c --- /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) + } + } +}