During the May Day holiday, I made up classes at home and saw the concept of two-way binding and one-way data flow. Watt, I thought Vue’s V-Model was a two-way data stream, but it’s not. Let me take a closer look

Two-way binding

In short, bidirectional binding means that updates to the Model trigger updates to the View, and updates to the View trigger updates to the Model, and their effects are mutual

Unidirectional data flow

In short, one-way data flow means that updates to the Model trigger updates to the View. Updates to the View do not trigger updates to the Model

Isn’t that bullshit? Everyone knows that

Now for the real work. Sit tight

  • Vue is a one-way data flow, not a two-way binding
  • Vue’s bidirectional binding is nothing more than syntactic sugar
  • Object.definepropert is used for reactive updates

The implementation principle of V-Model

  • Put on the component

The parent component


  <AnalysisSub v-model="phoneInfo" :zip-code.sync="zipCode" />
  
Copy the code

Child components

<template>
  <div>
    <input
      :value="phoneInfo.phone"
      type="number"
      placeholder="Mobile phone Number"
      @input="handlePhoneChange"
    />
    <input
      :value="zipCode"
      type="number"
      placeholder="Zip code"
      @input="handleZipCodeChange"
    />
  </div>
</template>
<script>
export default {
  name: "PersonalInfo",
  model: {
    prop: "phoneInfo", // Default value event:"change" // 默认 input
  },
  props: {
    phoneInfo: Object,
    zipCode: String
  },
  methods: {
    handlePhoneChange(e) {
      this.$emit("change", {
        ...this.phoneInfo,
        phone: e.target.value
      });
    },
    handleZipCodeChange(e) {
      this.$emit("update:zipCode", e.target.value); }}}; </script>Copy the code

The parent component is written the same as

 <AnalysisSub :phone-info="phoneInfo" @change="val => (phoneInfo = val)"
    :zip-code="zipCode"  @update:zipCode="val => (zipCode = val)"/>
Copy the code
  • Put it on the input element

In fact, the above has been reflected

< input v - model = "phoneInfo. Phone" / > < input: value ="PhoneInfo.phone" @input="val => { PhoneInfo.phone = val }"
Copy the code

The above two sentences are equivalent

TIPS

The model 2.2.0 +

Allows a custom component to customize prop and Event when using the V-Model. By default, a V-Model on a component uses value as a prop and input as an event, but some input types such as checkboxes and checkbox buttons may want to use Value Prop for different purposes. Using model options can sidestep the conflicts that arise from these situations.

.sync modifier 2.3.0+

In some cases, we may need to “bidirectional bind” a prop. Unfortunately, true bidirectional binding creates maintenance problems, because child components can modify the parent, and there is no obvious source of change in either parent or child.

conclusion

So, vUE is still a one-way data stream, and V-model is just syntactic sugar, which is a short form of :value=” STH “and @change=”val => STH = val”. We are often asked in interviews how Vue implements responsive updates to data, and interviewers expect to hear responses via the get and set methods of Object.defineProperty().

The V-model and.sync modifiers are used when a component has a single property and multiple properties that require bidirectional binding, respectively