diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index 57a314fff1..b39170dbd5 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -459,6 +459,15 @@ function processAttrs (el) { } } addAttr(el, name, JSON.stringify(value)) + // #4530 also bind special attributes as props even if they are static + // so that patches between dynamic/static are consistent + if (platformMustUseProp(el.tag, name)) { + if (name === 'value') { + addProp(el, name, JSON.stringify(value)) + } else { + addProp(el, name, 'true') + } + } } } } diff --git a/test/unit/modules/compiler/parser.spec.js b/test/unit/modules/compiler/parser.spec.js index deccb1efa3..fc78949631 100644 --- a/test/unit/modules/compiler/parser.spec.js +++ b/test/unit/modules/compiler/parser.spec.js @@ -391,7 +391,7 @@ describe('parser', () => { it('literal attribute', () => { // basic - const ast1 = parse('', baseOptions) + const ast1 = parse('', baseOptions) expect(ast1.attrsList[0].name).toBe('type') expect(ast1.attrsList[0].value).toBe('text') expect(ast1.attrsList[1].name).toBe('name') @@ -407,6 +407,13 @@ describe('parser', () => { expect(ast1.attrs[1].value).toBe('"field1"') expect(ast1.attrs[2].name).toBe('value') expect(ast1.attrs[2].value).toBe('"hello world"') + expect(ast1.attrs[3].name).toBe('checked') + expect(ast1.attrs[3].value).toBe('""') + // also bind speicals as props + expect(ast1.props[0].name).toBe('value') + expect(ast1.props[0].value).toBe('"hello world"') + expect(ast1.props[1].name).toBe('checked') + expect(ast1.props[1].value).toBe('true') // interpolation warning parse('', baseOptions) expect('Interpolation inside attributes has been removed').toHaveBeenWarned() diff --git a/test/unit/modules/vdom/patch/edge-cases.spec.js b/test/unit/modules/vdom/patch/edge-cases.spec.js index 5d374deae2..47c9effabc 100644 --- a/test/unit/modules/vdom/patch/edge-cases.spec.js +++ b/test/unit/modules/vdom/patch/edge-cases.spec.js @@ -114,4 +114,30 @@ describe('vdom patch: edge cases', () => { }) .then(done) }) + + // #4530 + it('should not reset value when patching bewteen dyanmic/static bindings', done => { + const vm = new Vue({ + data: { ok: true }, + template: ` +
+ + + + +
+ ` + }).$mount() + expect(vm.$el.children[0].value).toBe('a') + expect(vm.$el.children[1].checked).toBe(true) + vm.ok = false + waitForUpdate(() => { + expect(vm.$el.children[0].value).toBe('b') + expect(vm.$el.children[1].checked).toBe(false) + vm.ok = true + }).then(() => { + expect(vm.$el.children[0].value).toBe('a') + expect(vm.$el.children[1].checked).toBe(true) + }).then(done) + }) })