Evan You 10 лет назад
Родитель
Сommit
c350b76efb
3 измененных файлов с 64 добавлено и 9 удалено
  1. 18 3
      src/compiler/compile.js
  2. 23 5
      src/directives/public/show.js
  3. 23 1
      test/unit/specs/directives/public/show_spec.js

+ 18 - 3
src/compiler/compile.js

@@ -489,16 +489,25 @@ function checkComponent (el, options) {
  */
  */
 
 
 function checkTerminalDirectives (el, options) {
 function checkTerminalDirectives (el, options) {
-  if (_.attr(el, 'pre') !== null ||
-      el.hasAttribute('v-else')) {
+  // skip v-pre
+  if (_.attr(el, 'pre') !== null) {
     return skip
     return skip
   }
   }
+  // skip v-else block, but only if following v-if
+  if (el.hasAttribute('v-else')) {
+    var prev = el.previousElementSibling
+    if (prev && prev.hasAttribute('v-if')) {
+      return skip
+    }
+  }
   var value, dirName
   var value, dirName
   for (var i = 0, l = terminalDirectives.length; i < l; i++) {
   for (var i = 0, l = terminalDirectives.length; i < l; i++) {
     dirName = terminalDirectives[i]
     dirName = terminalDirectives[i]
-    if ((value = _.attr(el, dirName)) !== null) {
+    /* eslint-disable no-cond-assign */
+    if (value = el.getAttribute('v-' + dirName)) {
       return makeTerminalNodeLinkFn(el, dirName, value, options)
       return makeTerminalNodeLinkFn(el, dirName, value, options)
     }
     }
+    /* eslint-enable no-cond-assign */
   }
   }
 }
 }
 
 
@@ -592,6 +601,12 @@ function compileDirectives (attrs, options) {
       }
       }
       // extract directive name
       // extract directive name
       dirName = name.slice(2)
       dirName = name.slice(2)
+
+      // skip v-else (when used with v-show)
+      if (dirName === 'else') {
+        continue
+      }
+
       dirDef = resolveAsset(options, 'directives', dirName)
       dirDef = resolveAsset(options, 'directives', dirName)
 
 
       if (process.env.NODE_ENV !== 'production') {
       if (process.env.NODE_ENV !== 'production') {

+ 23 - 5
src/directives/public/show.js

@@ -1,8 +1,26 @@
+var _ = require('../../util')
 var transition = require('../../transition')
 var transition = require('../../transition')
 
 
-module.exports = function (value) {
-  var el = this.el
-  transition.apply(el, value ? 1 : -1, function () {
-    el.style.display = value ? '' : 'none'
-  }, this.vm)
+module.exports = {
+
+  bind: function () {
+    // check else block
+    var next = this.el.nextElementSibling
+    if (next && _.attr(next, 'else') !== null) {
+      this.elseEl = next
+    }
+  },
+
+  update: function (value) {
+    var el = this.el
+    transition.apply(el, value ? 1 : -1, function () {
+      el.style.display = value ? '' : 'none'
+    }, this.vm)
+    var elseEl = this.elseEl
+    if (elseEl) {
+      transition.apply(elseEl, value ? -1 : 1, function () {
+        elseEl.style.display = value ? 'none' : ''
+      }, this.vm)
+    }
+  }
 }
 }

+ 23 - 1
test/unit/specs/directives/public/show_spec.js

@@ -15,7 +15,7 @@ if (_.inBrowser) {
     it('should work', function () {
     it('should work', function () {
       var dir = {
       var dir = {
         el: el,
         el: el,
-        update: def,
+        update: def.update,
         vm: new Vue()
         vm: new Vue()
       }
       }
       dir.update(false)
       dir.update(false)
@@ -24,5 +24,27 @@ if (_.inBrowser) {
       expect(el.style.display).toBe('')
       expect(el.style.display).toBe('')
       expect(transition.apply).toHaveBeenCalled()
       expect(transition.apply).toHaveBeenCalled()
     })
     })
+
+    it('should work with v-else', function (done) {
+      var vm = new Vue({
+        el: el,
+        template:
+          '<p v-show="ok">YES</p>' +
+          '<p v-else>NO</p>',
+        data: {
+          ok: true
+        }
+      })
+      expect(el.children[0].style.display).toBe('')
+      expect(el.children[1].style.display).toBe('none')
+      expect(transition.apply.calls.count()).toBe(2)
+      vm.ok = false
+      Vue.nextTick(function () {
+        expect(el.children[0].style.display).toBe('none')
+        expect(el.children[1].style.display).toBe('')
+        expect(transition.apply.calls.count()).toBe(4)
+        done()
+      })
+    })
   })
   })
 }
 }