Problems and solutions encountered when using v-model to two-way bind the values ​​of parent-child components in Vue

Problems and solutions encountered when using v-model to two-way bind the values ​​of parent-child components in Vue

Scenario

Today, I encountered a strange problem when using v-model for two-way data binding of components. The webpage itself ran normally, but the browser kept showing 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"

This warning is caused 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 are using seems to be fine?

<main id="app">
 The currently 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, "Confidential").set(2, "Male").set(3, "Female"),
 sex: "",
 },
});

After testing, the program itself runs normally, there is no problem with the value transfer between parent and child components, and the two-way data binding does take effect, but the browser keeps reporting an error.

Try to solve

We found a way

  1. For variables that require two-way binding, declare a variable innerValue in the component data and initialize it to value
  2. Use v-model on select to bind this variable innerValue
  3. Monitor changes in value and modify the value of innerValue when value changes in the parent component
  4. Monitor changes in innerValue and use this.$emit('change', val) to tell the parent component that value needs to be updated when it changes.
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>
 `,
});

The usage code is exactly the same, but the code of the component RxSelect is much longer. . .

solve

A more elegant way is to use computed properties and their get/set , but the amount of code added is 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 details of the problems and solutions encountered when Vue uses v-model to two-way bind the values ​​of parent and child components. For more information about Vue using v-model to two-way bind the values ​​of parent and child components, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Example code of vue custom component to implement v-model two-way binding data
  • The use of v-model in vue3 components and in-depth explanation
  • Detailed explanation of the difference between v-model directive and .sync modifier in Vue
  • A brief discussion on the principle of Vue's two-way event binding v-model
  • Vue uses v-model to encapsulate the entire process of el-pagination components
  • Basic implementation method of cross-component binding using v-model in Vue
  • Solution for Vue form input box not supporting focus and blur events
  • Detailed usage of Vue's form input component using custom events [Date component and currency component]
  • Example code for Vue form input binding
  • Vue form input formatting Chinese input method abnormality
  • Vue form input binding v-model

<<:  MySQL uses triggers to solve the row limit of the table in the database. Detailed explanation and examples

>>:  Detailed explanation of three ways to configure Nginx virtual hosts (based on ports)

Recommend

mysql5.7.18.zip Installation-free version configuration tutorial (windows)

This is the installation tutorial of mysql5.7.18....

Use of Linux stat command

1. Command Introduction The stat command is used ...

A brief discussion on why daemon off is used when running nginx in docker

I'm very happy. When encountering this proble...

Detailed tutorial on Docker pulling Oracle 11g image configuration

Without further ado Start recording docker pullin...

Analysis of CocosCreator's new resource management system

Table of contents 1. Resources and Construction 1...

How to create a view on multiple tables in MySQL

In MySQL, create a view on two or more base table...

Detailed explanation of docker's high availability configuration

Docker Compose Docker Compose divides the managed...

Complete steps to build a squid proxy server in linux

Preface This article mainly introduces the releva...

How to set up scheduled tasks in Linux and Windows

Table of contents Linux 1. Basic use of crontab 2...

How to pass W3C validation?

In addition to setting regulations for various ta...

How to solve the problem of margin overlap

1. First, you need to know what will trigger the v...

Implementation example of Docker rocketmq deployment

Table of contents Preparation Deployment process ...

Let's talk about the problem of Vue integrating sweetalert2 prompt component

Table of contents 1. Project Integration 1. CDN i...

Detailed explanation of Docker container network port configuration process

Exposing network ports In fact, there are two par...

Founder font library Chinese and English file name comparison table

Founder Type Library is a font library developed ...