Преглед изворни кода

fix markStaticRoots with v-else (#4256)

chengchao пре 9 година
родитељ
комит
c1b84f87fb

+ 4 - 6
src/compiler/optimizer.js

@@ -77,14 +77,12 @@ function markStaticRoots (node: ASTNode, isInFor: boolean) {
     }
     if (node.children) {
       for (let i = 0, l = node.children.length; i < l; i++) {
-        const child = node.children[i]
-        isInFor = isInFor || !!node.for
-        markStaticRoots(child, isInFor)
-        if (child.type === 1 && child.elseBlock) {
-          markStaticRoots(child.elseBlock, isInFor)
-        }
+        markStaticRoots(node.children[i], isInFor || !!node.for)
       }
     }
+    if (node.elseBlock) {
+      markStaticRoots(node.elseBlock, isInFor)
+    }
   }
 }
 

+ 29 - 0
test/unit/features/directives/once.spec.js

@@ -213,6 +213,35 @@ describe('Directive v-once', () => {
     }).then(done)
   })
 
+  it('should work inside v-for with nested v-else', done => {
+    const vm = new Vue({
+      data: {
+        list: [{ id: 0, text: 'a', tester: true, truthy: 'y' }]
+      },
+      template: `
+        <div v-if="0"></div>
+        <div v-else>
+          <div v-for="i in list" :key="i.id">
+            <span v-if="i.tester" v-once>{{ i.truthy }}</span>
+            <span v-else v-once>{{ i.text }}</span>
+          </div>
+        </div>
+      `
+    }).$mount()
+
+    expectTextContent(vm, 'y')
+    vm.list[0].truthy = 'yy'
+    waitForUpdate(() => {
+      expectTextContent(vm, 'y')
+      vm.list[0].tester = false
+    }).then(() => {
+      expectTextContent(vm, 'a')
+      vm.list[0].text = 'nn'
+    }).then(() => {
+      expectTextContent(vm, 'a')
+    }).then(done)
+  })
+
   it('should warn inside non-keyed v-for', () => {
     const vm = new Vue({
       data: {

+ 14 - 0
test/unit/modules/compiler/optimizer.spec.js

@@ -209,4 +209,18 @@ describe('optimizer', () => {
     expect(ast.children[0].children[0].staticRoot).toBe(true)
     expect(ast.children[0].children[0].staticInFor).toBe(true)
   })
+
+  it('mark static trees inside v-for with nested v-else and v-once', () => {
+    const ast = parse(`
+      <div v-if="1"></div>
+      <div v-else>
+        <div v-for="i in 10" :key="i">
+          <div v-if="1">{{ i }}</div>
+          <div v-else v-once>{{ i }}</div>
+        </div>
+      <div>`, baseOptions)
+    optimize(ast, baseOptions)
+    expect(ast.elseBlock.children[0].children[0].elseBlock.staticRoot).toBe(false)
+    expect(ast.elseBlock.children[0].children[0].elseBlock.staticInFor).toBe(true)
+  })
 })