Skip to content

Commit 425d4d3

Browse files
committed
handle interpolations in <textarea> properly (fix #1109)
1 parent dd9d186 commit 425d4d3

File tree

4 files changed

+33
-15
lines changed

4 files changed

+33
-15
lines changed

src/compiler/compile.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,14 @@ function compileNode (node, options) {
232232
*/
233233

234234
function compileElement (el, options) {
235+
// preprocess textareas.
236+
// textarea treats its text content as the initial value.
237+
// just bind it as a v-attr directive for value.
238+
if (el.tagName === 'TEXTAREA') {
239+
if (textParser.parse(el.value)) {
240+
el.setAttribute('value', el.value)
241+
}
242+
}
235243
var linkFn
236244
var hasAttrs = el.hasAttributes()
237245
// check terminal directives (repeat & if)
@@ -250,16 +258,6 @@ function compileElement (el, options) {
250258
if (!linkFn && hasAttrs) {
251259
linkFn = compileDirectives(el.attributes, options)
252260
}
253-
// if the element is a textarea, we need to interpolate
254-
// its content on initial render.
255-
if (el.tagName === 'TEXTAREA') {
256-
var realLinkFn = linkFn
257-
linkFn = function (vm, el) {
258-
el.value = vm.$interpolate(el.value)
259-
if (realLinkFn) realLinkFn(vm, el)
260-
}
261-
linkFn.terminal = true
262-
}
263261
return linkFn
264262
}
265263

src/directives/attr.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ module.exports = {
3535
},
3636

3737
setAttr: function (attr, value) {
38-
if (value != null && value !== false) {
38+
if (attr === 'value' && attr in this.el) {
39+
if (!this.valueRemoved) {
40+
this.el.removeAttribute(attr)
41+
this.valueRemoved = true
42+
}
43+
this.el.value = value
44+
} else if (value != null && value !== false) {
3945
if (xlinkRE.test(attr)) {
4046
this.el.setAttributeNS(xlinkNS, attr, value)
4147
} else {
@@ -44,8 +50,5 @@ module.exports = {
4450
} else {
4551
this.el.removeAttribute(attr)
4652
}
47-
if (attr === 'value' && 'value' in this.el) {
48-
this.el.value = value
49-
}
5053
}
5154
}

test/unit/specs/directives/attr_spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ if (_.inBrowser) {
3030
dir.el = document.createElement('input')
3131
dir.arg = 'value'
3232
dir.update('what')
33-
expect(dir.el.getAttribute('value')).toBe('what')
33+
expect(dir.el.hasAttribute('value')).toBe(false)
3434
expect(dir.el.value).toBe('what')
3535
})
3636

test/unit/specs/misc_spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,4 +292,21 @@ describe('Misc', function () {
292292
}
293293
})
294294

295+
it('handle interpolated textarea', function (done) {
296+
var el = document.createElement('div')
297+
el.innerHTML = '<textarea>hello {{msg}}</textarea>'
298+
var vm = new Vue({
299+
el: el,
300+
data: {
301+
msg: 'test'
302+
}
303+
})
304+
expect(el.innerHTML).toBe('<textarea>hello test</textarea>')
305+
vm.msg = 'world'
306+
Vue.nextTick(function () {
307+
expect(el.innerHTML).toBe('<textarea>hello world</textarea>')
308+
done()
309+
})
310+
})
311+
295312
})

0 commit comments

Comments
 (0)