Skip to content

Commit 0c11aa8

Browse files
Hanks10100yyx990803
authored andcommitted
feat(weex): generate "@render" function for weex recycle-list (#6987)
* feat($compiler): support to generate @render function for weex recycle-list Compile the template twice with different options for weex platform if the “recyclable” flag is passed. Generate both normal render function and “@render” function for recycle-list. Adjust function names and arguments in recycle-list compiler. * test(weex): add test cases for <recycle-list>
1 parent 305ef28 commit 0c11aa8

28 files changed

+588
-30
lines changed

flow/compiler.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ declare type CompilerOptions = {
1717
shouldDecodeNewlines?: boolean;
1818
shouldDecodeNewlinesForHref?: boolean;
1919

20+
// support <recycle-list> in weex
21+
recyclable?: boolean;
22+
2023
// for ssr optimization compiler
2124
scopeId?: string;
2225

@@ -30,6 +33,7 @@ declare type CompilerOptions = {
3033
declare type CompiledResult = {
3134
ast: ?ASTElement;
3235
render: string;
36+
'@render'?: string;
3337
staticRenderFns: Array<string>;
3438
stringRenderFns?: Array<string>;
3539
errors?: Array<string>;

src/compiler/codegen/events.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,18 @@ export function genHandlers (
4848
4949
// Generate handler code with binding params on Weex
5050
function genWeexHandler (params: Array<any>, handlerCode: string) {
51-
const wrapperArgs = params.filter(exp => simplePathRE.test(exp) && exp !== '$event')
52-
const handlerParams = wrapperArgs.map(exp => ({ '@binding': exp }))
53-
wrapperArgs.push('$event')
54-
return '{' +
55-
`handler:function(${wrapperArgs.join(',')}){${handlerCode}},\n` +
56-
`params:${JSON.stringify(handlerParams)}` +
51+
let innerHandlerCode = handlerCode
52+
const exps = params.filter(exp => simplePathRE.test(exp) && exp !== '$event')
53+
const bindings = exps.map(exp => ({ '@binding': exp }))
54+
const args = exps.map((exp, i) => {
55+
const key = `$_${i + 1}`
56+
innerHandlerCode = innerHandlerCode.replace(exp, key)
57+
return key
58+
})
59+
args.push('$event')
60+
return '{\n' +
61+
`handler:function(${args.join(',')}){${innerHandlerCode}},\n` +
62+
`params:${JSON.stringify(bindings)}\n` +
5763
'}'
5864
}
5965

src/platforms/weex/compiler/index.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,28 @@ export const baseOptions: CompilerOptions = {
2323
isReservedTag,
2424
getTagNamespace,
2525
preserveWhitespace: false,
26+
recyclable: false,
2627
staticKeys: genStaticKeys(modules)
2728
}
2829

29-
const { compile, compileToFunctions } = createCompiler(baseOptions)
30-
export { compile, compileToFunctions }
30+
const compiler = createCompiler(baseOptions)
31+
32+
export function compile (
33+
template: string,
34+
options?: CompilerOptions
35+
): CompiledResult {
36+
let generateAltRender = false
37+
if (options && options.recyclable === true) {
38+
generateAltRender = true
39+
options.recyclable = false
40+
}
41+
const result = compiler.compile(template, options)
42+
43+
// generate @render function for <recycle-list>
44+
if (options && generateAltRender) {
45+
options.recyclable = true
46+
const { render } = compiler.compile(template, options)
47+
result['@render'] = render
48+
}
49+
return result
50+
}

src/platforms/weex/compiler/modules/recycle-list/index.js

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,42 @@
11
/* @flow */
22

3-
import { transformText } from './text'
4-
import { transformVBind } from './v-bind'
5-
import { transformVIf } from './v-if'
6-
import { transformVFor } from './v-for'
3+
import { postTransformText } from './text'
4+
import { preTransformVBind } from './v-bind'
5+
import { preTransformVIf } from './v-if'
6+
import { preTransformVFor } from './v-for'
77
import { postTransformVOn } from './v-on'
88

99
let currentRecycleList = null
1010

11+
function shouldCompile (el: ASTElement, options: CompilerOptions) {
12+
return options.recyclable ||
13+
(currentRecycleList && el !== currentRecycleList)
14+
}
15+
1116
function preTransformNode (el: ASTElement, options: CompilerOptions) {
1217
if (el.tag === 'recycle-list') {
1318
currentRecycleList = el
1419
}
15-
if (currentRecycleList) {
16-
// TODO
17-
transformVBind(el)
18-
transformVIf(el, options) // and v-else-if and v-else
19-
transformVFor(el, options)
20+
if (shouldCompile(el, options)) {
21+
preTransformVBind(el, options)
22+
preTransformVIf(el, options) // also v-else-if and v-else
23+
preTransformVFor(el, options)
2024
}
2125
}
2226

23-
function transformNode (el: ASTElement) {
24-
if (currentRecycleList) {
25-
// TODO
27+
function transformNode (el: ASTElement, options: CompilerOptions) {
28+
if (shouldCompile(el, options)) {
29+
// do nothing yet
2630
}
2731
}
2832

29-
function postTransformNode (el: ASTElement) {
30-
if (currentRecycleList) {
33+
function postTransformNode (el: ASTElement, options: CompilerOptions) {
34+
if (shouldCompile(el, options)) {
3135
// <text>: transform children text into value attr
3236
if (el.tag === 'text') {
33-
transformText(el)
37+
postTransformText(el, options)
3438
}
35-
postTransformVOn(el)
39+
postTransformVOn(el, options)
3640
}
3741
if (el === currentRecycleList) {
3842
currentRecycleList = null

src/platforms/weex/compiler/modules/recycle-list/text.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function genText (node: ASTNode) {
1313
return JSON.stringify(value)
1414
}
1515

16-
export function transformText (el: ASTElement) {
16+
export function postTransformText (el: ASTElement, options: CompilerOptions) {
1717
// weex <text> can only contain text, so the parser
1818
// always generates a single child.
1919
if (el.children.length) {

src/platforms/weex/compiler/modules/recycle-list/v-bind.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ function parseAttrName (name: string): string {
88
return camelize(name.replace(bindRE, ''))
99
}
1010

11-
export function transformVBind (el: ASTElement) {
11+
export function preTransformVBind (el: ASTElement, options: CompilerOptions) {
1212
for (const attr in el.attrsMap) {
1313
if (bindRE.test(attr)) {
1414
const name: string = parseAttrName(attr)

src/platforms/weex/compiler/modules/recycle-list/v-for.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { forAliasRE, forIteratorRE } from 'compiler/parser/index'
44
import { getAndRemoveAttr } from 'compiler/helpers'
55

6-
export function transformVFor (el: ASTElement, options: CompilerOptions) {
6+
export function preTransformVFor (el: ASTElement, options: CompilerOptions) {
77
const exp = getAndRemoveAttr(el, 'v-for')
88
if (!exp) {
99
return

src/platforms/weex/compiler/modules/recycle-list/v-if.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ function getPrevMatch (el: ASTElement): any {
1818
}
1919
}
2020

21-
export function transformVIf (el: ASTElement, options: CompilerOptions) {
21+
export function preTransformVIf (el: ASTElement, options: CompilerOptions) {
2222
if (hasConditionDirective(el)) {
2323
let exp
2424
const ifExp = getAndRemoveAttr(el, 'v-if')

src/platforms/weex/compiler/modules/recycle-list/v-on.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* @flow */
22

3-
const inlineStatementRE = /^\s*([A-Za-z_$0-9\.]+)*\s*\(\s*(([A-Za-z_$0-9\'\"]+)?(\s*,\s*([A-Za-z_$0-9\'\"]+))*)\s*\)$/
3+
const inlineStatementRE = /^\s*([A-Za-z_$0-9\['\."\]]+)*\s*\(\s*(([A-Za-z_$0-9\['\."\]]+)?(\s*,\s*([A-Za-z_$0-9\['\."\]]+))*)\s*\)$/
44

55
function parseHandlerParams (handler: ASTElementHandler) {
66
const res = inlineStatementRE.exec(handler.value)
@@ -9,7 +9,7 @@ function parseHandlerParams (handler: ASTElementHandler) {
99
}
1010
}
1111

12-
export function postTransformVOn (el: ASTElement) {
12+
export function postTransformVOn (el: ASTElement, options: CompilerOptions) {
1313
const events: ASTElementHandlers | void = el.events
1414
if (!events) {
1515
return

test/weex/cases/cases.spec.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,17 @@ describe('Usage', () => {
6868
describe('event', () => {
6969
it('click', createEventTestCase('event/click'))
7070
})
71+
72+
describe('recycle-list', () => {
73+
it('text node', createRenderTestCase('recycle-list/text-node'))
74+
it('attributes', createRenderTestCase('recycle-list/attrs'))
75+
it('v-if', createRenderTestCase('recycle-list/v-if'))
76+
it('v-else', createRenderTestCase('recycle-list/v-else'))
77+
it('v-else-if', createRenderTestCase('recycle-list/v-else-if'))
78+
it('v-for', createRenderTestCase('recycle-list/v-for'))
79+
it('v-for-iterator', createRenderTestCase('recycle-list/v-for-iterator'))
80+
it('v-on', createRenderTestCase('recycle-list/v-on'))
81+
it('v-on-inline', createRenderTestCase('recycle-list/v-on-inline'))
82+
})
7183
})
7284

0 commit comments

Comments
 (0)