Evan You 10 лет назад
Родитель
Сommit
534e12d15c
3 измененных файлов с 41 добавлено и 5 удалено
  1. 2 1
      src/compiler/compile.js
  2. 21 4
      src/directives/public/if.js
  3. 18 0
      test/unit/specs/directives/public/if_spec.js

+ 2 - 1
src/compiler/compile.js

@@ -488,7 +488,8 @@ function checkComponent (el, options) {
  */
 
 function checkTerminalDirectives (el, options) {
-  if (_.attr(el, 'pre') !== null) {
+  if (_.attr(el, 'pre') !== null ||
+      el.hasAttribute(config.prefix + 'else')) {
     return skip
   }
   var value, dirName

+ 21 - 4
src/directives/public/if.js

@@ -8,6 +8,13 @@ module.exports = {
   bind: function () {
     var el = this.el
     if (!el.__vue__) {
+      // check else block
+      var next = el.nextElementSibling
+      if (next && _.attr(next, 'else') !== null) {
+        _.remove(next)
+        this.elseFactory = new FragmentFactory(this.vm, next)
+      }
+      // check main block
       this.anchor = _.createAnchor('v-if')
       _.replace(el, this.anchor)
       this.factory = new FragmentFactory(this.vm, el)
@@ -32,15 +39,25 @@ module.exports = {
   },
 
   insert: function () {
+    if (this.elseFrag) {
+      this.elseFrag.remove()
+      this.elseFrag.destroy()
+      this.elseFrag = null
+    }
     this.frag = this.factory.create(this._host, this._scope, this._frag)
     this.frag.before(this.anchor)
   },
 
   remove: function () {
-    if (!this.frag) return
-    this.frag.remove()
-    this.frag.destroy()
-    this.frag = null
+    if (this.frag) {
+      this.frag.remove()
+      this.frag.destroy()
+      this.frag = null
+    }
+    if (this.elseFactory) {
+      this.elseFrag = this.elseFactory.create(this._host, this._scope, this._frag)
+      this.elseFrag.before(this.anchor)
+    }
   },
 
   unbind: function () {

+ 18 - 0
test/unit/specs/directives/public/if_spec.js

@@ -396,5 +396,23 @@ if (_.inBrowser) {
       expect(parentA).toBe(parentB)
     })
 
+    it('if + else', function (done) {
+      var vm = new Vue({
+        el: el,
+        data: { test: false, a: 'A', b: 'B' },
+        template: '<div v-if="test">{{a}}</div><div v-else>{{b}}</div>'
+      })
+      expect(el.textContent).toBe('B')
+      vm.test = true
+      _.nextTick(function () {
+        expect(el.textContent).toBe('A')
+        vm.test = false
+        _.nextTick(function () {
+          expect(el.textContent).toBe('B')
+          done()
+        })
+      })
+    })
+
   })
 }