refactor: reuse v-for parsing logic

This commit is contained in:
Evan You 2017-12-19 09:26:47 -05:00
parent 1dd6b6f046
commit 2e0f6d5d81
2 changed files with 47 additions and 39 deletions

View File

@ -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) {

View File

@ -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)
}