From a1d1145c9123f7175f3ac20b503cfa507ad455f4 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 10 Jul 2017 21:34:40 +0800 Subject: [PATCH] fix(v-model): should generate component-specific code for tags with "is" attribute fix #6066 --- src/compiler/parser/index.js | 4 ++- .../web/compiler/directives/model.js | 6 +++- .../directives/model-component.spec.js | 35 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index 48f4a06db9c..547b878db81 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -483,7 +483,9 @@ function processAttrs (el) { ) } } - if (isProp || platformMustUseProp(el.tag, el.attrsMap.type, name)) { + if (!el.component && ( + isProp || platformMustUseProp(el.tag, el.attrsMap.type, name) + )) { addProp(el, name, value) } else { addAttr(el, name, value) diff --git a/src/platforms/web/compiler/directives/model.js b/src/platforms/web/compiler/directives/model.js index 84e3dd46a38..72b3e6d67ac 100644 --- a/src/platforms/web/compiler/directives/model.js +++ b/src/platforms/web/compiler/directives/model.js @@ -40,7 +40,11 @@ export default function model ( } } - if (tag === 'select') { + if (el.component) { + genComponentModel(el, value, modifiers) + // component v-model doesn't need extra runtime + return false + } else if (tag === 'select') { genSelect(el, value, modifiers) } else if (tag === 'input' && type === 'checkbox') { genCheckboxModel(el, value, modifiers) diff --git a/test/unit/features/directives/model-component.spec.js b/test/unit/features/directives/model-component.spec.js index 52a0e4bd9e0..6098e4d6241 100644 --- a/test/unit/features/directives/model-component.spec.js +++ b/test/unit/features/directives/model-component.spec.js @@ -36,6 +36,41 @@ describe('Directive v-model component', () => { }).then(done) }) + it('should work with native tags with "is"', done => { + const vm = new Vue({ + data: { + msg: 'hello' + }, + template: ` +
+

{{ msg }}

+ +
+ `, + components: { + test: { + props: ['value'], + template: `` + } + } + }).$mount() + document.body.appendChild(vm.$el) + waitForUpdate(() => { + const input = vm.$el.querySelector('input') + input.value = 'world' + triggerEvent(input, 'input') + }).then(() => { + expect(vm.msg).toEqual('world') + expect(vm.$el.querySelector('p').textContent).toEqual('world') + vm.msg = 'changed' + }).then(() => { + expect(vm.$el.querySelector('p').textContent).toEqual('changed') + expect(vm.$el.querySelector('input').value).toEqual('changed') + }).then(() => { + document.body.removeChild(vm.$el) + }).then(done) + }) + it('should support customization via model option', done => { const spy = jasmine.createSpy('update') const vm = new Vue({