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

This commit is contained in:
Evan You 2015-08-01 10:50:31 -04:00
parent dd9d186679
commit 425d4d31dc
4 changed files with 33 additions and 15 deletions

View File

@ -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
}

View File

@ -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
}
}
}

View File

@ -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')
})

View File

@ -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()
})
})
})