Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v-model's value not in $attrs if value not defined as a prop #9330

Closed
lbogdan opened this issue Jan 16, 2019 · 2 comments · Fixed by #9331
Closed

v-model's value not in $attrs if value not defined as a prop #9330

lbogdan opened this issue Jan 16, 2019 · 2 comments · Fixed by #9331

Comments

@lbogdan
Copy link
Contributor

lbogdan commented Jan 16, 2019

Note: this issue only refers to v-model for components, and is not considering v-model on DOM elements. There was a discussion which included this unexpected behavior in #6216 , and also a PR #6327 that tried to fixed that, but those also included being able to pass-through v-model to DOM elements, which is not the case with this issue.

Version

2.5.22

Reproduction link

https://codesandbox.io/s/933003yx6w

Steps to reproduce

Use v-model on a component that doesn't have value defined in its props.

What is expected?

value is added to component's instance $attrs

What is actually happening?

value is not added to component's instance $attrs


Because of that, when wrapping a component and passing through the props and event handlers using v-bind="$attrs" v-on="$listeners", v-model will not be (completely) passed through, and will require explicitly defining value in wrapping component's props and passing it using :value="value" to the wrapped component (see the linked sandbox).

@lbogdan
Copy link
Contributor Author

lbogdan commented Jan 16, 2019

I already created a test that highlights the issue, and fixed it like so:

--- a/src/core/vdom/create-component.js
+++ b/src/core/vdom/create-component.js
@@ -250,7 +250,8 @@ function mergeHook (f1: any, f2: any): Function {
 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
+  const addTo = (options.props && prop in options.props) ? 'props' : 'attrs'
+  ;(data[addTo] || (data[addTo] = {}))[prop] = data.model.value
   const on = data.on || (data.on = {})
   const existing = on[event]
   const callback = data.model.callback

If you agree this is actually a bug that needs fixing, I can quickly open a PR.

@posva
Copy link
Member

posva commented Jan 16, 2019

yes, go ahead and create the PR. This would be more consistant. It already works with $listeners because they are bound to the on property

lbogdan added a commit to lbogdan/vue that referenced this issue Jan 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants