From 4df1f1df19f48f34ee394890e352ee78c95183f9 Mon Sep 17 00:00:00 2001 From: Daniel Duton Date: Mon, 2 Jul 2018 15:09:19 +0200 Subject: [PATCH 1/4] fix(v-model): transformModel should check if prop is defined and fallback to attrs if needed (issue #8430) --- src/core/vdom/create-component.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/vdom/create-component.js b/src/core/vdom/create-component.js index 8957822470b..ef590c395cc 100644 --- a/src/core/vdom/create-component.js +++ b/src/core/vdom/create-component.js @@ -247,7 +247,12 @@ function installComponentHooks (data: VNodeData) { function transformModel (options, data: any) { const prop = (options.model && options.model.prop) || 'value' const event = (options.model && options.model.event) || 'input' - ;(data.props || (data.props = {}))[prop] = data.model.value + // check if prop is defined, if not, attrs will be used + if (options.props && options.props[prop]) { + ;(data.props || (data.props = {}))[prop] = data.model.value + } else { + ;(data.attrs || (data.attrs = {}))[prop] = data.model.value + } const on = data.on || (data.on = {}) if (isDef(on[event])) { on[event] = [data.model.callback].concat(on[event]) From 5b36846a36cc12942fdda6602ef7909fd19b9a24 Mon Sep 17 00:00:00 2001 From: Daniel Duton Date: Mon, 2 Jul 2018 17:28:56 +0200 Subject: [PATCH 2/4] fix(v-model): transformModel should check if prop is defined and fall back to attrs if needed (fix #8430) --- src/core/vdom/create-component.js | 7 ++---- test/unit/features/options/model.spec.js | 27 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 test/unit/features/options/model.spec.js diff --git a/src/core/vdom/create-component.js b/src/core/vdom/create-component.js index ef590c395cc..c9b28fc4e89 100644 --- a/src/core/vdom/create-component.js +++ b/src/core/vdom/create-component.js @@ -248,11 +248,8 @@ function transformModel (options, data: any) { const prop = (options.model && options.model.prop) || 'value' const event = (options.model && options.model.event) || 'input' // check if prop is defined, if not, attrs will be used - if (options.props && options.props[prop]) { - ;(data.props || (data.props = {}))[prop] = data.model.value - } else { - ;(data.attrs || (data.attrs = {}))[prop] = data.model.value - } + const propOrAttrKey = options.props && options.props[prop] ? 'props' : 'attrs' + ;(data[propOrAttrKey] || (data[propOrAttrKey] = {}))[prop] = data.model.value const on = data.on || (data.on = {}) if (isDef(on[event])) { on[event] = [data.model.callback].concat(on[event]) diff --git a/test/unit/features/options/model.spec.js b/test/unit/features/options/model.spec.js new file mode 100644 index 00000000000..02e7a8ab1d9 --- /dev/null +++ b/test/unit/features/options/model.spec.js @@ -0,0 +1,27 @@ +import Vue from 'vue' + +describe('Options model', () => { + it('key should fallback to attrs if prop is not defined in component', () => { + const ChildComp = { + model: { + prop: 'value', + event: 'update:value' + }, + render: () => {} + } + + const vm = new Vue({ + components: { + ChildComp + }, + data () { + return { + value: 'value' + } + }, + template: '' + }).$mount() + + expect(vm.$refs['child-comp'].$attrs.value).toEqual(vm.value) + }) +}) From ed9f3a7d29ecb1cc02c15ac050f78c72f9fc93c3 Mon Sep 17 00:00:00 2001 From: Daniel Duton Date: Tue, 3 Jul 2018 08:45:50 +0200 Subject: [PATCH 3/4] fix(v-model): transformModel should check if prop is defined and fall back to attrs if needed (fix #8430) --- .../directives/model-component.spec.js | 20 ++++++++++++++ test/unit/features/options/model.spec.js | 27 ------------------- 2 files changed, 20 insertions(+), 27 deletions(-) delete mode 100644 test/unit/features/options/model.spec.js diff --git a/test/unit/features/directives/model-component.spec.js b/test/unit/features/directives/model-component.spec.js index 6098e4d6241..49463eaefe0 100644 --- a/test/unit/features/directives/model-component.spec.js +++ b/test/unit/features/directives/model-component.spec.js @@ -148,4 +148,24 @@ describe('Directive v-model component', () => { vm.$refs.input.$emit('input', ' foo o ') expect(vm.text).toBe('foo o') }) + + it('adds value to $attrs if no prop is defined', () => { + const Test = { + render: () => {} + } + + const vm = new Vue({ + components: { + Test + }, + data () { + return { + value: 'value' + } + }, + template: '' + }).$mount() + + expect(vm.$refs['test'].$attrs.value).toEqual(vm.value) + }) }) diff --git a/test/unit/features/options/model.spec.js b/test/unit/features/options/model.spec.js deleted file mode 100644 index 02e7a8ab1d9..00000000000 --- a/test/unit/features/options/model.spec.js +++ /dev/null @@ -1,27 +0,0 @@ -import Vue from 'vue' - -describe('Options model', () => { - it('key should fallback to attrs if prop is not defined in component', () => { - const ChildComp = { - model: { - prop: 'value', - event: 'update:value' - }, - render: () => {} - } - - const vm = new Vue({ - components: { - ChildComp - }, - data () { - return { - value: 'value' - } - }, - template: '' - }).$mount() - - expect(vm.$refs['child-comp'].$attrs.value).toEqual(vm.value) - }) -}) From 9ef1bc8aa0b3e596f4dfeb2d0b4c08a94d9461f7 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Tue, 3 Jul 2018 19:18:02 +0200 Subject: [PATCH 4/4] chore: refactor --- test/unit/features/directives/model-component.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/features/directives/model-component.spec.js b/test/unit/features/directives/model-component.spec.js index 49463eaefe0..041ba19d64e 100644 --- a/test/unit/features/directives/model-component.spec.js +++ b/test/unit/features/directives/model-component.spec.js @@ -166,6 +166,6 @@ describe('Directive v-model component', () => { template: '' }).$mount() - expect(vm.$refs['test'].$attrs.value).toEqual(vm.value) + expect(vm.$refs.test.$attrs.value).toEqual(vm.value) }) })