Quellcode durchsuchen

handle interpolations in <textarea> properly (fix #1109)

Evan You vor 11 Jahren
Ursprung
Commit
425d4d31dc

+ 8 - 10
src/compiler/compile.js

@@ -232,6 +232,14 @@ function compileNode (node, options) {
  */
 
 function compileElement (el, options) {
+  // preprocess textareas.
+  // textarea treats its text content as the initial value.
+  // just bind it as a v-attr directive for value.
+  if (el.tagName === 'TEXTAREA') {
+    if (textParser.parse(el.value)) {
+      el.setAttribute('value', el.value)
+    }
+  }
   var linkFn
   var hasAttrs = el.hasAttributes()
   // check terminal directives (repeat & if)
@@ -250,16 +258,6 @@ function compileElement (el, options) {
   if (!linkFn && hasAttrs) {
     linkFn = compileDirectives(el.attributes, options)
   }
-  // if the element is a textarea, we need to interpolate
-  // its content on initial render.
-  if (el.tagName === 'TEXTAREA') {
-    var realLinkFn = linkFn
-    linkFn = function (vm, el) {
-      el.value = vm.$interpolate(el.value)
-      if (realLinkFn) realLinkFn(vm, el)
-    }
-    linkFn.terminal = true
-  }
   return linkFn
 }
 

+ 7 - 4
src/directives/attr.js

@@ -35,7 +35,13 @@ module.exports = {
   },
 
   setAttr: function (attr, value) {
-    if (value != null && value !== false) {
+    if (attr === 'value' && attr in this.el) {
+      if (!this.valueRemoved) {
+        this.el.removeAttribute(attr)
+        this.valueRemoved = true
+      }
+      this.el.value = value
+    } else if (value != null && value !== false) {
       if (xlinkRE.test(attr)) {
         this.el.setAttributeNS(xlinkNS, attr, value)
       } else {
@@ -44,8 +50,5 @@ module.exports = {
     } else {
       this.el.removeAttribute(attr)
     }
-    if (attr === 'value' && 'value' in this.el) {
-      this.el.value = value
-    }
   }
 }

+ 1 - 1
test/unit/specs/directives/attr_spec.js

@@ -30,7 +30,7 @@ if (_.inBrowser) {
       dir.el = document.createElement('input')
       dir.arg = 'value'
       dir.update('what')
-      expect(dir.el.getAttribute('value')).toBe('what')
+      expect(dir.el.hasAttribute('value')).toBe(false)
       expect(dir.el.value).toBe('what')
     })
 

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

@@ -292,4 +292,21 @@ describe('Misc', function () {
     }
   })
 
+  it('handle interpolated textarea', function (done) {
+    var el = document.createElement('div')
+    el.innerHTML = '<textarea>hello {{msg}}</textarea>'
+    var vm = new Vue({
+      el: el,
+      data: {
+        msg: 'test'
+      }
+    })
+    expect(el.innerHTML).toBe('<textarea>hello test</textarea>')
+    vm.msg = 'world'
+    Vue.nextTick(function () {
+      expect(el.innerHTML).toBe('<textarea>hello world</textarea>')
+      done()
+    })
+  })
+
 })