Scene
Use todayv-model
I encountered a strange problem when performing two-way data binding of components. The web page itself is running normally and the browser keeps warning messages.
[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"
What caused this warning was a custom componentRxSelect
("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 fine?
<main > The currently selected gender is: {{(sex)}} <div> <rx-select :map="map" v-model="sex" /> </div> </main>
JavaScript Code
new Vue({ el: "#app", data: { map: new Map().set(1, "Confidential").set(2, "male").set(3, "female"), sex: "", }, });
After testing, the program itself is running normally, and there is no problem with passing the value of the parent-child component. The two-way data binding is indeed effective, but the browser keeps reporting errors.
Try to solve it
We found a way
- For variables that require two-way binding, inside the component
data
Declare a variableinnerValue
and initialize it tovalue
- exist
select
Use onv-model
Bind this variableinnerValue
- monitor
value
Changes in parent componentvalue
Modify when changesinnerValue
Value of - monitor
innerValue
Changes, use when changesthis.$emit('change', val)
Tell the parent component that needs to be updatedvalue
Value of
("RxSelect", { model: { prop: "value", event: "change", }, props: { value: [Number, String], map: Map, }, data() { return { innerValue: , }; }, watch: { value(val) { = 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> `, });
Using the code exactly the same, however the componentsRxSelect
There are a lot more codes. . .
solve
A more elegant way is to usecomputed
Computational properties and theirget/set
, the code increase is acceptable
("RxSelect", { model: { prop: "value", event: "change", }, props: { value: [Number, String], map: Map, }, computed: { innerValue: { get() { return ; }, 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 detailed content of the problems and solutions encountered when using vue to bidirectionally bind the values of parent-child components with v-model. For more information about vue to bidirectionally bind the values of parent-child components with v-model, please pay attention to my other related articles!