VueJS 2: cannot set two-way data-binding for input components












0















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).










share|improve this question

























  • 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











  • 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
















0















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).










share|improve this question

























  • 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











  • 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














0












0








0








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).










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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



















  • 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











  • 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

















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












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
});


}
});














draft saved

draft discarded


















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
















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

Npm cannot find a required file even through it is in the searched directory