VueJS 2: cannot set two-way data-binding for input components
Being quite new to Vue, I ran into the issue when I cannot establish binding between input/select tags inside components and the data inside Vue instance.
Example #1:
html
<sidebar-select
:title="UI.sidebar.localeSelect.title"
:name="UI.sidebar.localeSelect.name"
:options="UI.sidebar.localeSelect.options"
:vmodel="selectedLocale">
</sidebar-select>
<sidebar-select
:title="UI.sidebar.currencySelect.title"
:name="UI.sidebar.currencySelect.name"
:options="UI.sidebar.currencySelect.options"
:vmodel="state.currency">
</sidebar-select>
js - component
Vue.component('sidebar-select', {
props: ['title', 'name', 'options', 'vmodel'],
data() {
return {
vmodel: this.value
}
},
template: `<div class="col-xs-12 col-md-6" style="padding-left:0;padding-right:30px">
<div class="cg">
<label :for="name"><h4>{{ title }}</h4></label>
<select class="form-control form-horizontal" style="max-width: 300px"
:name="name"
v-model="vmodel">
<option v-for="option in options" :value="option.value">{{ option.text }}</option>
</select>
</div>
</div>`
});
js - data part
var app = new Vue({
el: '#app',
data: {
selectedLocale: 'ru',
user: {
'ru': {
name: 'Саша',
surname: 'Найдович',
position: 'программист',
phone: '1234567',
email: 'jdlfh@jdlbf.com'
},
'en': {
name: 'Alex',
surname: 'Naidovich',
position: 'frontend',
phone: '1234567',
email: '1234567@email.eu'
}
},
state: {
locale: 'ru',
currency: '€',
/* *** */
},
UI: {
sidebar: {
localeSelect: {
title: 'Язык КП',
name: 'offer-lang',
options: [
{value: 'en', text: 'International - English'},
/* *** */
{value: 'ru', text: 'Русский'}
],
preSelected: 'ru',
stateprop: 'locale'
},
currencySelect: {
title: 'Валюта КП',
name: 'offer-curr',
options: [
{value: '$', text: '$ (Dollar)'},
{value: '€', text: '€ (Euro)'},
{value: '₤', text: '₤ (UK Фунт)'},
{value: '₽', text: '₽ (RUS Рубль)'},
{value: '', text: 'Ввести вручную'}
],
preSelected: '€',
stateprop: 'currency'
},
} /* etc */
}
}
});
There are 2 errors I run into: [Vue warn]: The data property "vmodel" is already declared as a prop. Use prop default value instead.
at init and [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "vmodel"
vhen I try to change selects. I wish to know what am I doing wrong and what would be the best-practice way for this case.
UPDATE: the main question is about how to properly use v-model
two-way-data-binding when passing v-model
as an argument into the props
of component.
To be updated: example #2 with text inputs will be added tomorrow (the code is left at work).
javascript vue.js vuejs2
add a comment |
Being quite new to Vue, I ran into the issue when I cannot establish binding between input/select tags inside components and the data inside Vue instance.
Example #1:
html
<sidebar-select
:title="UI.sidebar.localeSelect.title"
:name="UI.sidebar.localeSelect.name"
:options="UI.sidebar.localeSelect.options"
:vmodel="selectedLocale">
</sidebar-select>
<sidebar-select
:title="UI.sidebar.currencySelect.title"
:name="UI.sidebar.currencySelect.name"
:options="UI.sidebar.currencySelect.options"
:vmodel="state.currency">
</sidebar-select>
js - component
Vue.component('sidebar-select', {
props: ['title', 'name', 'options', 'vmodel'],
data() {
return {
vmodel: this.value
}
},
template: `<div class="col-xs-12 col-md-6" style="padding-left:0;padding-right:30px">
<div class="cg">
<label :for="name"><h4>{{ title }}</h4></label>
<select class="form-control form-horizontal" style="max-width: 300px"
:name="name"
v-model="vmodel">
<option v-for="option in options" :value="option.value">{{ option.text }}</option>
</select>
</div>
</div>`
});
js - data part
var app = new Vue({
el: '#app',
data: {
selectedLocale: 'ru',
user: {
'ru': {
name: 'Саша',
surname: 'Найдович',
position: 'программист',
phone: '1234567',
email: 'jdlfh@jdlbf.com'
},
'en': {
name: 'Alex',
surname: 'Naidovich',
position: 'frontend',
phone: '1234567',
email: '1234567@email.eu'
}
},
state: {
locale: 'ru',
currency: '€',
/* *** */
},
UI: {
sidebar: {
localeSelect: {
title: 'Язык КП',
name: 'offer-lang',
options: [
{value: 'en', text: 'International - English'},
/* *** */
{value: 'ru', text: 'Русский'}
],
preSelected: 'ru',
stateprop: 'locale'
},
currencySelect: {
title: 'Валюта КП',
name: 'offer-curr',
options: [
{value: '$', text: '$ (Dollar)'},
{value: '€', text: '€ (Euro)'},
{value: '₤', text: '₤ (UK Фунт)'},
{value: '₽', text: '₽ (RUS Рубль)'},
{value: '', text: 'Ввести вручную'}
],
preSelected: '€',
stateprop: 'currency'
},
} /* etc */
}
}
});
There are 2 errors I run into: [Vue warn]: The data property "vmodel" is already declared as a prop. Use prop default value instead.
at init and [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "vmodel"
vhen I try to change selects. I wish to know what am I doing wrong and what would be the best-practice way for this case.
UPDATE: the main question is about how to properly use v-model
two-way-data-binding when passing v-model
as an argument into the props
of component.
To be updated: example #2 with text inputs will be added tomorrow (the code is left at work).
javascript vue.js vuejs2
1 - Look your <SidebarSelect /> component, you are passing vmodel as prop, and you also define it in the data section. 2 - You can't mutate a prop, you have to emit an event with the new value and the parent must update the value and send to the child the new one
– DobleL
Nov 21 '18 at 15:10
@DobleL thanks. Had kind of the same thought about the 1st error. But could you pls expand the point about the 2nd one? What I've tried is passing a handler as prop, and this handler was able to change data prop, and threw no errors. But when I try to change the state prop from console, the changed values didn't reach the component's view. And, the main question was about how to properly usev-model
two-way-data-binding when passingv-model
as an argument into theprops
of component.
– Alex Naidovich
Nov 21 '18 at 17:24
in a theorical scenario, and following the parent-child comunications, you can't mutate a property cuz the parent is not going to notice. the best practice is to emit (this.$emit) some event and handle it within the parent, but you actually can do what you want but using a .sync modifier. ievmodel.sync="data"
and then you can mutate in the child and will be syncrhonized with the paren
– DobleL
Nov 21 '18 at 17:31
add a comment |
Being quite new to Vue, I ran into the issue when I cannot establish binding between input/select tags inside components and the data inside Vue instance.
Example #1:
html
<sidebar-select
:title="UI.sidebar.localeSelect.title"
:name="UI.sidebar.localeSelect.name"
:options="UI.sidebar.localeSelect.options"
:vmodel="selectedLocale">
</sidebar-select>
<sidebar-select
:title="UI.sidebar.currencySelect.title"
:name="UI.sidebar.currencySelect.name"
:options="UI.sidebar.currencySelect.options"
:vmodel="state.currency">
</sidebar-select>
js - component
Vue.component('sidebar-select', {
props: ['title', 'name', 'options', 'vmodel'],
data() {
return {
vmodel: this.value
}
},
template: `<div class="col-xs-12 col-md-6" style="padding-left:0;padding-right:30px">
<div class="cg">
<label :for="name"><h4>{{ title }}</h4></label>
<select class="form-control form-horizontal" style="max-width: 300px"
:name="name"
v-model="vmodel">
<option v-for="option in options" :value="option.value">{{ option.text }}</option>
</select>
</div>
</div>`
});
js - data part
var app = new Vue({
el: '#app',
data: {
selectedLocale: 'ru',
user: {
'ru': {
name: 'Саша',
surname: 'Найдович',
position: 'программист',
phone: '1234567',
email: 'jdlfh@jdlbf.com'
},
'en': {
name: 'Alex',
surname: 'Naidovich',
position: 'frontend',
phone: '1234567',
email: '1234567@email.eu'
}
},
state: {
locale: 'ru',
currency: '€',
/* *** */
},
UI: {
sidebar: {
localeSelect: {
title: 'Язык КП',
name: 'offer-lang',
options: [
{value: 'en', text: 'International - English'},
/* *** */
{value: 'ru', text: 'Русский'}
],
preSelected: 'ru',
stateprop: 'locale'
},
currencySelect: {
title: 'Валюта КП',
name: 'offer-curr',
options: [
{value: '$', text: '$ (Dollar)'},
{value: '€', text: '€ (Euro)'},
{value: '₤', text: '₤ (UK Фунт)'},
{value: '₽', text: '₽ (RUS Рубль)'},
{value: '', text: 'Ввести вручную'}
],
preSelected: '€',
stateprop: 'currency'
},
} /* etc */
}
}
});
There are 2 errors I run into: [Vue warn]: The data property "vmodel" is already declared as a prop. Use prop default value instead.
at init and [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "vmodel"
vhen I try to change selects. I wish to know what am I doing wrong and what would be the best-practice way for this case.
UPDATE: the main question is about how to properly use v-model
two-way-data-binding when passing v-model
as an argument into the props
of component.
To be updated: example #2 with text inputs will be added tomorrow (the code is left at work).
javascript vue.js vuejs2
Being quite new to Vue, I ran into the issue when I cannot establish binding between input/select tags inside components and the data inside Vue instance.
Example #1:
html
<sidebar-select
:title="UI.sidebar.localeSelect.title"
:name="UI.sidebar.localeSelect.name"
:options="UI.sidebar.localeSelect.options"
:vmodel="selectedLocale">
</sidebar-select>
<sidebar-select
:title="UI.sidebar.currencySelect.title"
:name="UI.sidebar.currencySelect.name"
:options="UI.sidebar.currencySelect.options"
:vmodel="state.currency">
</sidebar-select>
js - component
Vue.component('sidebar-select', {
props: ['title', 'name', 'options', 'vmodel'],
data() {
return {
vmodel: this.value
}
},
template: `<div class="col-xs-12 col-md-6" style="padding-left:0;padding-right:30px">
<div class="cg">
<label :for="name"><h4>{{ title }}</h4></label>
<select class="form-control form-horizontal" style="max-width: 300px"
:name="name"
v-model="vmodel">
<option v-for="option in options" :value="option.value">{{ option.text }}</option>
</select>
</div>
</div>`
});
js - data part
var app = new Vue({
el: '#app',
data: {
selectedLocale: 'ru',
user: {
'ru': {
name: 'Саша',
surname: 'Найдович',
position: 'программист',
phone: '1234567',
email: 'jdlfh@jdlbf.com'
},
'en': {
name: 'Alex',
surname: 'Naidovich',
position: 'frontend',
phone: '1234567',
email: '1234567@email.eu'
}
},
state: {
locale: 'ru',
currency: '€',
/* *** */
},
UI: {
sidebar: {
localeSelect: {
title: 'Язык КП',
name: 'offer-lang',
options: [
{value: 'en', text: 'International - English'},
/* *** */
{value: 'ru', text: 'Русский'}
],
preSelected: 'ru',
stateprop: 'locale'
},
currencySelect: {
title: 'Валюта КП',
name: 'offer-curr',
options: [
{value: '$', text: '$ (Dollar)'},
{value: '€', text: '€ (Euro)'},
{value: '₤', text: '₤ (UK Фунт)'},
{value: '₽', text: '₽ (RUS Рубль)'},
{value: '', text: 'Ввести вручную'}
],
preSelected: '€',
stateprop: 'currency'
},
} /* etc */
}
}
});
There are 2 errors I run into: [Vue warn]: The data property "vmodel" is already declared as a prop. Use prop default value instead.
at init and [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "vmodel"
vhen I try to change selects. I wish to know what am I doing wrong and what would be the best-practice way for this case.
UPDATE: the main question is about how to properly use v-model
two-way-data-binding when passing v-model
as an argument into the props
of component.
To be updated: example #2 with text inputs will be added tomorrow (the code is left at work).
javascript vue.js vuejs2
javascript vue.js vuejs2
edited Nov 21 '18 at 17:26
Alex Naidovich
asked Nov 21 '18 at 14:50


Alex NaidovichAlex Naidovich
113
113
1 - Look your <SidebarSelect /> component, you are passing vmodel as prop, and you also define it in the data section. 2 - You can't mutate a prop, you have to emit an event with the new value and the parent must update the value and send to the child the new one
– DobleL
Nov 21 '18 at 15:10
@DobleL thanks. Had kind of the same thought about the 1st error. But could you pls expand the point about the 2nd one? What I've tried is passing a handler as prop, and this handler was able to change data prop, and threw no errors. But when I try to change the state prop from console, the changed values didn't reach the component's view. And, the main question was about how to properly usev-model
two-way-data-binding when passingv-model
as an argument into theprops
of component.
– Alex Naidovich
Nov 21 '18 at 17:24
in a theorical scenario, and following the parent-child comunications, you can't mutate a property cuz the parent is not going to notice. the best practice is to emit (this.$emit) some event and handle it within the parent, but you actually can do what you want but using a .sync modifier. ievmodel.sync="data"
and then you can mutate in the child and will be syncrhonized with the paren
– DobleL
Nov 21 '18 at 17:31
add a comment |
1 - Look your <SidebarSelect /> component, you are passing vmodel as prop, and you also define it in the data section. 2 - You can't mutate a prop, you have to emit an event with the new value and the parent must update the value and send to the child the new one
– DobleL
Nov 21 '18 at 15:10
@DobleL thanks. Had kind of the same thought about the 1st error. But could you pls expand the point about the 2nd one? What I've tried is passing a handler as prop, and this handler was able to change data prop, and threw no errors. But when I try to change the state prop from console, the changed values didn't reach the component's view. And, the main question was about how to properly usev-model
two-way-data-binding when passingv-model
as an argument into theprops
of component.
– Alex Naidovich
Nov 21 '18 at 17:24
in a theorical scenario, and following the parent-child comunications, you can't mutate a property cuz the parent is not going to notice. the best practice is to emit (this.$emit) some event and handle it within the parent, but you actually can do what you want but using a .sync modifier. ievmodel.sync="data"
and then you can mutate in the child and will be syncrhonized with the paren
– DobleL
Nov 21 '18 at 17:31
1 - Look your <SidebarSelect /> component, you are passing vmodel as prop, and you also define it in the data section. 2 - You can't mutate a prop, you have to emit an event with the new value and the parent must update the value and send to the child the new one
– DobleL
Nov 21 '18 at 15:10
1 - Look your <SidebarSelect /> component, you are passing vmodel as prop, and you also define it in the data section. 2 - You can't mutate a prop, you have to emit an event with the new value and the parent must update the value and send to the child the new one
– DobleL
Nov 21 '18 at 15:10
@DobleL thanks. Had kind of the same thought about the 1st error. But could you pls expand the point about the 2nd one? What I've tried is passing a handler as prop, and this handler was able to change data prop, and threw no errors. But when I try to change the state prop from console, the changed values didn't reach the component's view. And, the main question was about how to properly use
v-model
two-way-data-binding when passing v-model
as an argument into the props
of component.– Alex Naidovich
Nov 21 '18 at 17:24
@DobleL thanks. Had kind of the same thought about the 1st error. But could you pls expand the point about the 2nd one? What I've tried is passing a handler as prop, and this handler was able to change data prop, and threw no errors. But when I try to change the state prop from console, the changed values didn't reach the component's view. And, the main question was about how to properly use
v-model
two-way-data-binding when passing v-model
as an argument into the props
of component.– Alex Naidovich
Nov 21 '18 at 17:24
in a theorical scenario, and following the parent-child comunications, you can't mutate a property cuz the parent is not going to notice. the best practice is to emit (this.$emit) some event and handle it within the parent, but you actually can do what you want but using a .sync modifier. ie
vmodel.sync="data"
and then you can mutate in the child and will be syncrhonized with the paren– DobleL
Nov 21 '18 at 17:31
in a theorical scenario, and following the parent-child comunications, you can't mutate a property cuz the parent is not going to notice. the best practice is to emit (this.$emit) some event and handle it within the parent, but you actually can do what you want but using a .sync modifier. ie
vmodel.sync="data"
and then you can mutate in the child and will be syncrhonized with the paren– DobleL
Nov 21 '18 at 17:31
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414646%2fvuejs-2-cannot-set-two-way-data-binding-for-input-components%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414646%2fvuejs-2-cannot-set-two-way-data-binding-for-input-components%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1 - Look your <SidebarSelect /> component, you are passing vmodel as prop, and you also define it in the data section. 2 - You can't mutate a prop, you have to emit an event with the new value and the parent must update the value and send to the child the new one
– DobleL
Nov 21 '18 at 15:10
@DobleL thanks. Had kind of the same thought about the 1st error. But could you pls expand the point about the 2nd one? What I've tried is passing a handler as prop, and this handler was able to change data prop, and threw no errors. But when I try to change the state prop from console, the changed values didn't reach the component's view. And, the main question was about how to properly use
v-model
two-way-data-binding when passingv-model
as an argument into theprops
of component.– Alex Naidovich
Nov 21 '18 at 17:24
in a theorical scenario, and following the parent-child comunications, you can't mutate a property cuz the parent is not going to notice. the best practice is to emit (this.$emit) some event and handle it within the parent, but you actually can do what you want but using a .sync modifier. ie
vmodel.sync="data"
and then you can mutate in the child and will be syncrhonized with the paren– DobleL
Nov 21 '18 at 17:31