From 2e0f6d5d817957ab23819f90b264243d87ef968c Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 19 Dec 2017 09:26:47 -0500 Subject: [PATCH] refactor: reuse v-for parsing logic --- src/compiler/parser/index.js | 44 +++++++++++-------- .../compiler/modules/recycle-list/v-for.js | 42 +++++++++--------- 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index 0261934f..82df3d35 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -4,8 +4,8 @@ import he from 'he' import { parseHTML } from './html-parser' import { parseText } from './text-parser' import { parseFilters } from './filter-parser' -import { cached, no, camelize } from 'shared/util' import { genAssignmentCode } from '../directives/model' +import { extend, cached, no, camelize } from 'shared/util' import { isIE, isEdge, isServerRendering } from 'core/util/env' import { @@ -23,7 +23,7 @@ export const onRE = /^@|^v-on:/ export const dirRE = /^v-|^@|^:/ export const forAliasRE = /(.*?)\s+(?:in|of)\s+(.*)/ export const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/ -export const stripParensRE = /^\(|\)$/g +const stripParensRE = /^\(|\)$/g const argRE = /:(.*)$/ export const bindRE = /^:|^v-bind:/ @@ -355,28 +355,36 @@ function processRef (el) { export function processFor (el: ASTElement) { let exp if ((exp = getAndRemoveAttr(el, 'v-for'))) { - const inMatch = exp.match(forAliasRE) - if (!inMatch) { - process.env.NODE_ENV !== 'production' && warn( + const res = parseFor(exp) + if (res) { + extend(el, res) + } else if (process.env.NODE_ENV !== 'production') { + warn( `Invalid v-for expression: ${exp}` ) - return - } - el.for = inMatch[2].trim() - const alias = inMatch[1].trim().replace(stripParensRE, '') - const iteratorMatch = alias.match(forIteratorRE) - if (iteratorMatch) { - el.alias = alias.replace(forIteratorRE, '') - el.iterator1 = iteratorMatch[1].trim() - if (iteratorMatch[2]) { - el.iterator2 = iteratorMatch[2].trim() - } - } else { - el.alias = alias } } } +export function parseFor (exp: string): ?Object { + const inMatch = exp.match(forAliasRE) + if (!inMatch) return + const res = {} + res.for = inMatch[2].trim() + const alias = inMatch[1].trim().replace(stripParensRE, '') + const iteratorMatch = alias.match(forIteratorRE) + if (iteratorMatch) { + res.alias = alias.replace(forIteratorRE, '') + res.iterator1 = iteratorMatch[1].trim() + if (iteratorMatch[2]) { + res.iterator2 = iteratorMatch[2].trim() + } + } else { + res.alias = alias + } + return res +} + function processIf (el) { const exp = getAndRemoveAttr(el, 'v-if') if (exp) { diff --git a/src/platforms/weex/compiler/modules/recycle-list/v-for.js b/src/platforms/weex/compiler/modules/recycle-list/v-for.js index 3433288f..9f09e4b4 100644 --- a/src/platforms/weex/compiler/modules/recycle-list/v-for.js +++ b/src/platforms/weex/compiler/modules/recycle-list/v-for.js @@ -1,6 +1,6 @@ /* @flow */ -import { forAliasRE, forIteratorRE, stripParensRE } from 'compiler/parser/index' +import { parseFor } from 'compiler/parser/index' import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers' export function preTransformVFor (el: ASTElement, options: WeexCompilerOptions) { @@ -8,26 +8,26 @@ export function preTransformVFor (el: ASTElement, options: WeexCompilerOptions) if (!exp) { return } - const inMatch = exp.match(forAliasRE) - if (inMatch) { - const alias = inMatch[1].trim().replace(stripParensRE, '') - const desc: Object = { - '@expression': inMatch[2].trim(), - '@alias': alias + + const res = parseFor(exp) + if (!res) { + if (process.env.NODE_ENV !== 'production' && options.warn) { + options.warn(`Invalid v-for expression: ${exp}`) } - const iteratorMatch = alias.match(forIteratorRE) - if (iteratorMatch) { - desc['@alias'] = alias.replace(forIteratorRE, '') - if (iteratorMatch[2]) { - desc['@key'] = iteratorMatch[1].trim() - desc['@index'] = iteratorMatch[2].trim() - } else { - desc['@index'] = iteratorMatch[1].trim() - } - } - delete el.attrsMap['v-for'] - addRawAttr(el, '[[repeat]]', desc) - } else if (process.env.NODE_ENV !== 'production' && options.warn) { - options.warn(`Invalid v-for expression: ${exp}`) + return } + + const desc: Object = { + '@expression': res.for, + '@alias': res.alias + } + if (res.iterator2) { + desc['@key'] = res.iterator1 + desc['@index'] = res.iterator2 + } else { + desc['@index'] = res.iterator1 + } + + delete el.attrsMap['v-for'] + addRawAttr(el, '[[repeat]]', desc) }