I'am searching a way to use v-model and :value in same time on the same object.
I got this error:
:value="user.firstName"conflicts withv-modelon the same element because the latter already expands to a value binding internally.
The purpose is to set as default value the value get from the mapGetters (coming from one store) and to set the right value when the user will submit the modification. (in onSubmit)
<div class="form-group m-form__group row">
<label for="example-text-input" class="col-2 col-form-label">
{{ $t("firstname") }}
</label>
<div class="col-7">
<input class="form-control m-input" type="text" v-model="firstname" :value="user.firstName">
</div>
</div>
<script>
import { mapGetters, mapActions } from 'vuex';
export default {
data () {
return {
lang: "",
firstname: ""
}
},
computed: mapGetters([
'user'
]),
methods: {
...mapActions([
'updateUserProfile'
]),
onChangeLanguage () {
this.$i18n.locale = lang;
},
// Function called when user click on the "Save changes" btn
onSubmit () {
console.log('Component(Profile)::onSaveChanges() - called');
const userData = {
firstName: this.firstname
}
console.log('Component(Profile)::onSaveChanges() - called', userData);
//this.updateUserProfile(userData);
},
// Function called when user click on the "Cancel" btn
onCancel () {
console.log('Component(Profile)::onCancel() - called');
this.$router.go(-1);
}
}
}
</script>
Two-way binding is a powerful feature that, if used properly, can significantly speed up your development process. It reduces the complexity of keeping user input consistent with the application data model. In Vue, two-way binding is accomplished using the v-model directive.
v-model is for two way bindings means: if you change input value, the bound data will be changed and vice versa. But v-bind:value is called one way binding that means: you can change input value by changing bound data but you can't change bound data by changing input value through the element.
In Vue. js, we do not have to write a lot of lines to have two-way data binding, unlike other frameworks. One-way data binding means that the variable is just bound to the DOM.
lazy. By default, v-model syncs with the state of the Vue instance (data properties) on every input event - which means every single time the value of our input changes. The . lazy modifier changes our v-model so it only syncs after change events.
Typically you want to set the "initial" value of the v-model on the object itself, like:
data() {
return {
firstname: 'someName'
}
}
But since you're getting it from the store, you could access the specific getter object with this.$store.getters[your_object], so I would remove the :value binding and use v-model alone for this:
<div class="col-7">
<input class="form-control m-input" type="text" v-model="firstname">
</div>
<script>
export default {
data() {
return {
lang: "",
firstname: this.$store.getters.user.firstName
}
},
// ...
}
</script>
The Vue v-model directive is syntactic sugar over v-bind:value and v-on:input. This alligator.io article helped me a lot to understand how it works.
So basically your problem is that the v-model directive sets value to firstname, while you're also explicitly setting value to user.firstName.
There are a lot of ways to handle this issue. I think a fast and straightforward solution is to store the firstname as a data variable (as you're already doing), and then use only v-model with it, disregarding v-bind:value.
Then, to set the user from the store for the default username, you could set fristname as the store user's username in the created hook:
<script>
import { mapGetters, mapActions } from 'vuex';
export default {
created() {
this.firstname = this.user.username; // is this right? no used to the map getters syntax, but this is the idea
},
data () {
return {
lang: "",
firstname: ""
}
},
computed: mapGetters([
'user'
]),
methods: {
...mapActions([
'updateUserProfile'
]),
onChangeLanguage () {
this.$i18n.locale = lang;
},
// Function called when user click on the "Save changes" btn
onSubmit () {
console.log('Component(Profile)::onSaveChanges() - called');
const userData = {
firstName: this.firstname
}
console.log('Component(Profile)::onSaveChanges() - called', userData);
//this.updateUserProfile(userData);
},
// Function called when user click on the "Cancel" btn
onCancel () {
console.log('Component(Profile)::onCancel() - called');
this.$router.go(-1);
}
}
}
</script>
You should only use v-model, it will create a 2-way binding with the value in your script: changing the variable in js will update the input element, interacting with the input element will update the variable.
If you want to use a default value, just set the variable to that value (wherever it may come from).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With