The best way of state synchronization of Vue parent-child components

Time:2021-6-15

hello everyone! I am papaya, too fragrant! A front-end engineer, I wrote an article beforeThe best way to synchronize the state of Vue parent child componentsThis article describes the best way to synchronize parent-child components in most cases. It is also recommended by open source China. Thank you!

As a continuation, this is a supplement to the special situation of the previous article, and will give a more detailed description and code demonstration. Of course, if you just look at this article to solve specific problems, it is also feasible.

For parent-child component state synchronization, this articleThe best way to synchronize the state of Vue parent child componentsThis paper describes the optimal solution in most cases, but the situation may be different when we want to create reusable components and encapsulated logic to behave as consistent as possible. For example, we now want to encapsulate an input box component calledMyInputWe know that ordinary input boxes are usually usedv-modelTo do two-way data binding, here if you want the encapsulatedMyInputComponent in use is consistent with the ordinary input box, we will inevitably let custom components also supportv-modelIn fact, it also involves the state synchronization of parent-child components, which can be basically realized in the way we talked about before, but only with the help ofvueThe exposed API can make our writing more elegant. Next, we use different ways to implement this component.

The original implementation

CustomMyInputassembly

export default {
  name: "MyInput",
  props: {
      //It can also be written as' V-model ': string, but it is suggested to hump directly if there are no quotation marks on the left
    vModel: String
  },
  methods: {
    inputHandle (event) {
        //Note: it is used here update:v-model  Or update:vModel  Fine
      this.$emit("update:v-model", event.target.value)
    }
  }

}

Usage

//Mode one

//Mode 2

You can see that the original way can also be realized, but in terms of usev-modelIf it is regarded as an attribute, it must be added before it:You can use dynamic attributes, and the result becomes:v-modelThen we remove the event binding to simplify the writing, and our final effect is:v-model.syncThis kind of writing always makes people feel strange. Next, let’s solve this problem

Implementation of Vue API

CustomMyInputassembly

export default {
  name: "MyInput",
  props: {
    value: String
  },
  methods: {
    inputHandle (event) {
      this.$emit("input", event.target.value)
    }
  }

}

Usage

See here may be a part of the students face confused force, this is synchronized? EMM, it’s really synchronized, sovalueFrom where,inputEvents are not bound. Indeed, we have omitted all of these. In fact, this is the convenience that Vue’s API brings us when we try to transfer them to custom componentsv-modelFor this special attribute, Vue will do two things for us, one is tov-modelThis is why we need to write props value internally. The other is to listen to the input event on the current custom component and assign the first parameter to thev-modelVariables in the. You can see that Vue has done a lot of practical work for us where we can’t see it with naked eyes, but we need to understand why he has done so much for you. It’s not difficult to see that these logics are repeated many times in the business scenario. If Vue doesn’t do it for you, you have to do it yourself, and you will be in trouble! Of course, it’s not over yet! Next is more wonderful!

Is an attributevalueAnd eventsinputname

Sometimes we may want value to be passed down as a common attribute, and input in our business scenario is not good enough as an event. Anyway, value and input do not conform to the semantics of your business. At this time, I want to change my name. What should I do? Next, let’s look at the following code:

export default {
  name: "MyInput",
  model: {
    Prop: "text", // the attribute name
    event: " update:v-model "// change the event name
  }
  props: {
    Text: string // even if the name is changed, it is necessary here
  },
  methods: {
    inputHandle (event) {
      this.$emit("update:v-model", event.target.value)
    }
  }

}

The above shows how we can change our name. In fact, we have changed the accepted field names in props, and then added the model option. It should be noted that no matter what, the fields in props are indispensable.

Practical application: parent child component state synchronization

As the title says, this API can still be used for state synchronization of parent-child components in some special cases. Here is an actual example. Suppose we use a framework, which provides us with a modal box component named modal. This component needs to add V-model attribute to show and hide the modal box. Usually, our modal box has a lot of logic, At this time, we will consider encapsulating it into a custom component. At this time, we hope that the encapsulated component and the original modal box component will have the same way of using it. We will add V-model to show and hide it. Is it time that the function we talked about is particularly suitable?

If you have front-end problems to discuss, you can add mine qun:237871108 . You can also find me by searching for papaya Tai Xiang in BiliBili.