Przeglądaj źródła

class interpolation should preserve transition class (fix #1960)

Evan You 10 lat temu
rodzic
commit
212eb80113
2 zmienionych plików z 31 dodań i 11 usunięć
  1. 19 11
      src/directives/public/bind.js
  2. 12 0
      test/unit/specs/misc_spec.js

+ 19 - 11
src/directives/public/bind.js

@@ -1,4 +1,4 @@
-import { warn } from '../../util/index'
+import { warn, setClass } from '../../util/index'
 import { BIND } from '../priorities'
 import vStyle from '../internal/style'
 
@@ -87,12 +87,13 @@ export default {
   handleObject: vStyle.handleObject,
 
   handleSingle (attr, value) {
+    const el = this.el
     if (
       !this.descriptor.interp &&
       attrWithPropsRE.test(attr) &&
-      attr in this.el
+      attr in el
     ) {
-      this.el[attr] = attr === 'value'
+      el[attr] = attr === 'value'
         ? value == null // IE9 will set input.value to "null" for null...
           ? ''
           : value
@@ -101,27 +102,34 @@ export default {
     // set model props
     var modelProp = modelProps[attr]
     if (modelProp) {
-      this.el[modelProp] = value
+      el[modelProp] = value
       // update v-model if present
-      var model = this.el.__v_model
+      var model = el.__v_model
       if (model) {
         model.listener()
       }
     }
     // do not set value attribute for textarea
-    if (attr === 'value' && this.el.tagName === 'TEXTAREA') {
-      this.el.removeAttribute(attr)
+    if (attr === 'value' && el.tagName === 'TEXTAREA') {
+      el.removeAttribute(attr)
       return
     }
     // update attribute
     if (value != null && value !== false) {
-      if (xlinkRE.test(attr)) {
-        this.el.setAttributeNS(xlinkNS, attr, value)
+      if (attr === 'class') {
+        // handle edge case #1960:
+        // class interpolation should not overwrite Vue transition class
+        if (el.__v_trans) {
+          value += ' ' + el.__v_trans.id + '-transition'
+        }
+        setClass(el, value)
+      } else if (xlinkRE.test(attr)) {
+        el.setAttributeNS(xlinkNS, attr, value)
       } else {
-        this.el.setAttribute(attr, value)
+        el.setAttribute(attr, value)
       }
     } else {
-      this.el.removeAttribute(attr)
+      el.removeAttribute(attr)
     }
   }
 }

+ 12 - 0
test/unit/specs/misc_spec.js

@@ -416,4 +416,16 @@ describe('Misc', function () {
     })
     expect(vm.$el.firstChild.getAttribute('class')).toBe('si-icon def abc')
   })
+
+  // #1960
+  it('class interpolation should preserve transition class', function () {
+    var vm = new Vue({
+      el: document.createElement('div'),
+      template: '<div class="{{test}}" transition="test"></div>',
+      data: {
+        test: 'hi'
+      }
+    })
+    expect(vm.$el.firstChild.className).toBe('hi test-transition')
+  })
 })