Bladeren bron

fix: fix v-for iterator parsing destructuring + parens without index

Evan You 8 jaren geleden
bovenliggende
commit
aa8262540a

+ 3 - 2
src/compiler/parser/index.js

@@ -22,7 +22,8 @@ import {
 export const onRE = /^@|^v-on:/
 export const dirRE = /^v-|^@|^:/
 export const forAliasRE = /(.*?)\s+(?:in|of)\s+(.*)/
-export const forIteratorRE = /\((\{[^}]*\}|[^,]*),([^,]*)(?:,([^,]*))?\)/
+export const forIteratorRE = /\((\{[^}]*\}|[^,{]*),([^,]*)(?:,([^,]*))?\)/
+const stripParensRE = /^\(|\)$/g
 
 const argRE = /:(.*)$/
 const bindRE = /^:|^v-bind:/
@@ -364,7 +365,7 @@ export function processFor (el: ASTElement) {
         el.iterator2 = iteratorMatch[3].trim()
       }
     } else {
-      el.alias = alias
+      el.alias = alias.replace(stripParensRE, '')
     }
   }
 }

+ 6 - 6
test/unit/features/directives/for.spec.js

@@ -464,20 +464,20 @@ describe('Directive v-for', () => {
     }).then(done)
   })
 
-  const supportsDeconstruct = (() => {
+  const supportsDestructuring = (() => {
     try {
       new Function('var { foo } = bar')
       return true
     } catch (e) {}
   })()
 
-  if (supportsDeconstruct) {
-    it('should support deconstruct syntax in alias position', () => {
+  if (supportsDestructuring) {
+    it('should support destructuring syntax in alias position', () => {
       const vm = new Vue({
-        data: { list: [{ foo: 'hi' }] },
-        template: '<div><div v-for="({ foo }, i) in list">{{ foo }}{{ i }}</div></div>'
+        data: { list: [{ foo: 'hi', bar: 'ho' }] },
+        template: '<div><div v-for="({ foo, bar }, i) in list">{{ foo }} {{ bar }} {{ i }}</div></div>'
       }).$mount()
-      expect(vm.$el.textContent).toBe('hi0')
+      expect(vm.$el.textContent).toBe('hi ho 0')
     })
   }
 })

+ 39 - 0
test/unit/modules/compiler/parser.spec.js

@@ -283,6 +283,45 @@ describe('parser', () => {
     expect(liAst.key).toBe('item.uid')
   })
 
+  it('v-for directive destructuring', () => {
+    let ast = parse('<ul><li v-for="{ foo } in items"></li></ul>', baseOptions)
+    let liAst = ast.children[0]
+    expect(liAst.for).toBe('items')
+    expect(liAst.alias).toBe('{ foo }')
+
+    // with paren
+    ast = parse('<ul><li v-for="({ foo }) in items"></li></ul>', baseOptions)
+    liAst = ast.children[0]
+    expect(liAst.for).toBe('items')
+    expect(liAst.alias).toBe('{ foo }')
+
+    // multi-var destructuring
+    ast = parse('<ul><li v-for="{ foo, bar, baz } in items"></li></ul>', baseOptions)
+    liAst = ast.children[0]
+    expect(liAst.for).toBe('items')
+    expect(liAst.alias).toBe('{ foo, bar, baz }')
+
+    // multi-var destructuring with paren
+    ast = parse('<ul><li v-for="({ foo, bar, baz }) in items"></li></ul>', baseOptions)
+    liAst = ast.children[0]
+    expect(liAst.for).toBe('items')
+    expect(liAst.alias).toBe('{ foo, bar, baz }')
+
+    // with index
+    ast = parse('<ul><li v-for="({ foo }, i) in items"></li></ul>', baseOptions)
+    liAst = ast.children[0]
+    expect(liAst.for).toBe('items')
+    expect(liAst.alias).toBe('{ foo }')
+    expect(liAst.iterator1).toBe('i')
+
+    // multi-var destructuring with index
+    ast = parse('<ul><li v-for="({ foo, bar, baz }, i) in items"></li></ul>', baseOptions)
+    liAst = ast.children[0]
+    expect(liAst.for).toBe('items')
+    expect(liAst.alias).toBe('{ foo, bar, baz }')
+    expect(liAst.iterator1).toBe('i')
+  })
+
   it('v-for directive invalid syntax', () => {
     parse('<ul><li v-for="item into items"></li></ul>', baseOptions)
     expect('Invalid v-for expression').toHaveBeenWarned()