Problems and Solutions of vue Using v model Bidirectional Binding Parent child Component Values
- 2021-11-01 01:50:19
- OfStack
Scene
In use today
v-model
I encountered a strange problem when carrying out bidirectional data binding of components. The web page itself runs normally, and a warning message appears in Browser 1.
[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: "value"
This warning is raised by a custom component
RxSelect
Vue.component("RxSelect", {
model: {
prop: "value",
event: "change",
},
props: {
value: [Number, String],
map: Map,
},
template: `
<select
v-model="value"
@change="$emit('change', value)"
>
<option
v-for="[k,v] in map"
:value="k"
:key="k"
>{{v}}</option>
</select>
`,
});
The code we use seems to be nothing wrong with the code?
<main id="app">
The current selected gender is : {{map.get(sex)}}
<div>
<rx-select :map="map" v-model="sex" />
</div>
</main>
JavaScript code
new Vue({
el: "#app",
data: {
map: new Map().set(1, " Secrecy ").set(2, " Male ").set(3, " Female "),
sex: "",
},
});
After testing, the program itself runs normally, and the value transmission of father and son components is no problem. Bidirectional data binding does take effect, but the browser is 1 straight error.
Try to solve
We have found a way
Inside the component for variables that require bidirectional bindingdata
Declare 1 variable
innerValue
And initialized to
value
In
select
Use on
v-model
Bind this variable
innerValue
Eavesdropping
value
In the parent component
value
Modify when changing
innerValue
Value of
Eavesdropping
innerValue
Change, use when changing
this.$emit('change', val)
Tell the parent component that it needs to be updated
value
Value of
Vue.component("RxSelect", {
model: {
prop: "value",
event: "change",
},
props: {
value: [Number, String],
map: Map,
},
data() {
return {
innerValue: this.value,
};
},
watch: {
value(val) {
this.innerValue = val;
},
innerValue(val) {
this.$emit("change", val);
},
},
template: `
<select v-model="innerValue">
<option
v-for="[k,v] in map"
:value="k"
:key="k"
>{{v}}</option>
</select>
`,
});
Use code completely 1 sample, but component
RxSelect
There is a lot more code. . .
Solve
A more elegant way is to use
computed
Calculate properties and their
get/set
The degree of code increase is still acceptable
Vue.component("RxSelect", {
model: {
prop: "value",
event: "change",
},
props: {
value: [Number, String],
map: Map,
},
computed: {
innerValue: {
get() {
return this.value;
},
set(val) {
this.$emit("change", val);
},
},
},
template: `
<select v-model="innerValue">
<option
v-for="[k,v] in map"
:value="k"
:key="k"
>{{v}}</option>
</select>
`,
});
The above is the vue use v-model bidirectional binding parent-child component value encountered problems and solutions in detail, more about vue use v-model bidirectional binding parent-child component value information please pay attention to other related articles on this site!