Vue2 subcomponents bind v-model to realize parent-child component communication

foreword

v-model can be used on components for two-way binding.

First let's recall the usage of v-model on native elements:

<input v-model="firstName" />

Behind the scenes, the template compiler does a more verbose equivalent expansion of the v-model . So the code above is actually equivalent to the following:

<input
  :value="firstName"
  @input="firstName = $event.target.value"
/>

default usage

parent component

<template>
  <div>
    <h1>{
    
    { first }}-{
    
    { last }}</h1>
    <UserName
      :firstName="first"
      :lastName="last"
      @update:firstName="func1"
      @update:lastName="func2"
    />
  </div>
</template>

<script>
import UserName from "./UserName.vue";
export default {
  name: "V-Model",
  components: {
    UserName,
  },
  data() {
    return {
      first: "000",
      last: "123",
    };
  },
  methods: {
    // 默认用法
    func1(val) {
      this.first = val;
    },
    func2(val) {
      this.last = val;
    },
  },
};
</script>

Subassembly

<template>
  <div>
    <input v-model="first" type="text" @input="input1" />
    <input v-model="last" type="text" @input="input2" />
  </div>
</template>

<script>
export default {
  name: "UserName",
  props: ["firstName", "lastName"],

  data() {
    return {
      first: this.firstName,
      last: this.lastName,
    };
  },
  methods: {
    input1() {
      this.$emit("update:firstName", this.first);
    },
    input2() {
      this.$emit("update:lastName", this.last);
    },
  },
};
</script>

The above can realize the two-way binding of parent-child components



.sync wording

Adding .sync when passing parameters will simplify the above writing, and the parent component does not need to define an update trigger function (update)

 <UserName :firstName.sync="first" />

would be expanded to:

<UserName :firstName="first" @update:firstName="val => first = val"></UserName>

When the child component needs to update the value of firstName , it needs to explicitly trigger an update event:

this.$emit('update:firstName', newValue)

parent component

<template>
  <div>
    <h1>{
    
    { first }}-{
    
    { last }}</h1>
    <UserName :firstName.sync="first" :lastName.sync="last" />
  </div>
</template>

<script>
import UserName from "./UserName.vue";
export default {
  name: "V-Model",
  components: {
    UserName,
  },

  data() {
    return {
      first: "000",
      last: "123",
    };
  },
  methods: {
   
  },
};
</script>

Subassembly

<template>
  <div>
    <input type="text" :value="firstName" @input="$emit('update:firstName', $event.target.value)" />
    <input type="text" :value="lastName" @input="$emit('update:lastName', $event.target.value)" />
  </div>
</template>

<script>
export default {
  name: "UserName",
  components: {},
  props: ["firstName", "lastName"],
  data() {
    return {};
  },
  methods: {},
};
</script>

The above can also achieve two-way binding of parent-child components



Bind a single v-model

When used on a component, v-model will be expanded as follows:

 <UserName v-model="first"  />
 <!-- 上面等同于下面的写法 -->
<UserName
  :modelValue="first"
  @input="first= $event.target.value"
/>

parent component

<template>
  <div>
    <h1>{
    
    { first }}-{
    
    { last }}</h1>
    <UserName v-model="first"  />
  </div>
</template>

<script>
import UserName from "./UserName.vue";
export default {
  name: "V-Model",
  components: {
    UserName,
  },

  data() {
    return {
      first: "000",
      last: "123",
    };
  },
  methods: {
    
  },
};
</script>

Subassembly

<template>
  <div>
    <input
      type="text"
      :value="firstName"
      @input="$emit('update', $event.target.value)"
    />
  </div>
</template>

<script>
export default {
  name: "UserName",
  components: {},
  props: ["firstName"],
  model: {
    prop: "firstName",
    event: "update",
  },

  data() {
    return {};
  },
};
</script>

Single input box binding is now possible



If there is an error in the article, please ask everyone to ask questions, I would be very grateful. If you don't understand, you can comment, and I will reply one by one.

If the article is helpful to everyone, I hope you can give it a thumbs up and encourage it. There will be a long way to go to work together in the future, and the road will be long and difficult.

Guess you like

Origin blog.csdn.net/qq_52855464/article/details/129762831