Browse Source

feat($compiler): supports compiling v-else-if and v-else to the weex native directive

Hanks 8 years ago
parent
commit
2a1ce0d92c

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

@@ -7,15 +7,15 @@ import { transformVFor } from './v-for'
 
 let currentRecycleList = null
 
-function preTransformNode (el: ASTElement) {
+function preTransformNode (el: ASTElement, options: CompilerOptions) {
   if (el.tag === 'recycle-list') {
     currentRecycleList = el
   }
   if (currentRecycleList) {
     // TODO
     transformVBind(el)
-    transformVIf(el)
-    transformVFor(el)
+    transformVIf(el, options) // and v-else-if and v-else
+    transformVFor(el, options)
   }
 }
 

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

@@ -3,7 +3,7 @@
 import { forAliasRE, forIteratorRE } from 'compiler/parser/index'
 import { getAndRemoveAttr } from 'compiler/helpers'
 
-export function transformVFor (el: ASTElement) {
+export function transformVFor (el: ASTElement, options: CompilerOptions) {
   const exp = getAndRemoveAttr(el, 'v-for')
   if (!exp) {
     return
@@ -27,5 +27,7 @@ export function transformVFor (el: ASTElement) {
     delete el.attrsMap['v-for']
     el.attrsMap['[[repeat]]'] = desc
     el.attrsList.push({ name: '[[repeat]]', value: desc })
+  } else if (process.env.NODE_ENV !== 'production' && options.warn) {
+    options.warn(`Invalid v-for expression: ${exp}`)
   }
 }

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

@@ -2,12 +2,47 @@
 
 import { getAndRemoveAttr } from 'compiler/helpers'
 
-export function transformVIf (el: ASTElement) {
-  const exp = getAndRemoveAttr(el, 'v-if')
-  if (exp) {
+function hasConditionDirective (el: ASTElement): boolean {
+  for (const attr in el.attrsMap) {
+    if (/^v\-if|v\-else|v\-else\-if$/.test(attr)) {
+      return true
+    }
+  }
+  return false
+}
+
+function getPrevMatch (el: ASTElement): any {
+  if (el.parent && el.parent.children) {
+    const prev: Object = el.parent.children[el.parent.children.length - 1]
+    return prev.attrsMap['[[match]]']
+  }
+}
+
+export function transformVIf (el: ASTElement, options: CompilerOptions) {
+  if (hasConditionDirective(el)) {
+    let exp
+    const ifExp = getAndRemoveAttr(el, 'v-if')
+    const elseifExp = getAndRemoveAttr(el, 'v-else-if')
+    if (ifExp) {
+      exp = ifExp
+    } else {
+      const prevMatch = getPrevMatch(el)
+      if (prevMatch) {
+        exp = elseifExp
+          ? `!(${prevMatch}) && (${elseifExp})` // v-else-if
+          : `!(${prevMatch})` // v-else
+      } else if (process.env.NODE_ENV !== 'production' && options.warn) {
+        options.warn(
+          `v-${elseifExp ? ('else-if="' + elseifExp + '"') : 'else'} ` +
+          `used on element <${el.tag}> without corresponding v-if.`
+        )
+        return
+      }
+    }
     el.attrsMap['[[match]]'] = exp
     el.attrsList.push({ name: '[[match]]', value: exp })
     delete el.attrsMap['v-if']
+    delete el.attrsMap['v-else-if']
+    delete el.attrsMap['v-else']
   }
-  // TODO: support v-else and v-else-if
 }