I was a little bit suspicious when I saw this unidirectional data flow in the VUE documentation. I was a little bit suspicious when I saw this unidirectional data flow in the VUE documentation. Still a little confused. Hence this article.

Let’s start with the V-Model

1. V-model is used on input elements

V-models are used much like bidirectional bindings (and actually…). But Vue is a monomial data stream and V-Model is just syntactic sugar:

<input v-model="something" />
<input v-bind:value="something" v-on:input="something = $event.target.value" />
Copy the code

The first line of code is really just syntax sugar on the second line. And then the second line of code could be shortened like this:

<input :value="something" @input="something = $event.target.value" />
Copy the code

To understand this line of code, the first thing you need to know is that the input element itself has an onInput event, which is a new addition to HTML5, similar to onchange, which will trigger onInput whenever the content of the input field changes. Pass the latest value to something via $event.

If we look closely at the syntax sugar and the original syntax lines, we can conclude that when we add a V-model attribute to an input element, by default value is the attribute of the element, and the ‘input’ event is the trigger that passes the value in real time

2. V-models are used on components

The V-model can be used not only on input, but also on components, as shown in the demo on the website.

<currency-input v-model="price"></currency-input> Vue.component('currency-input', { template: '\ <span>\ $\ <input\ ref="input"\ v-bind:value="value"\ v-on:input="updateValue($event.target.value)"\ >\ </span>\ ', Props: ['value'], // why is value used here? Where is value defined? Methods: {// Instead of updating the value directly, use this method to format the input value and limit the number of bits. Slice (0, value.indexof ('.') === -1? Function (value) {var formattedValue = value; Value.length: value.indexof ('.') + 3) // If (formattedValue! $refs.input. Value = formattedValue} -- Why is 'input' the name of the event that triggers the event? Where is' input 'defined? --> this.$emit('input', Number(formattedValue)) } } })Copy the code

If you know the answer to both of these questions, congratulations, you really know the V-Model. If you don’t, take a look at this code:

<currency-input v-model="price"></currency-input> so when used in components, it is equivalent to the following shorthand: </currency-input :value="price" @input="price = arguments[0]">Copy the code

So, by default, when you add a V-Model property to a component, value is the component’s property and then the ‘input’ value is the name of the event that you bind to the component. This is especially useful when writing components.

3. Disadvantages and solutions of V-Model

The V-Model is not useful when creating common components like checkboxes or checkboxes.

<input type="checkbox" v-model="something" />
Copy the code

The V-Model gives us the value property and the onInput event, but instead of the value property, we need the Checked property, and when you click on this checkbox it doesn’t fire the onInput event, it just fires the onchange event.

Since the V-model only applies to the input element, this situation is easy to solve:

<input type="checkbox" :checked="value" @change="change(value, $event)"
Copy the code

When v-Model is used on components:

<checkbox v-model="value"></checkbox> Vue.component('checkbox', { tempalte: '<input type="checkbox" @change="change" :checked="currentValue"/>' props: ['value'], data: Function () {return {// define a local variable and initialize it with the value of prop. currentValue: this.value }; }, methods: { change: function ($event) { this.currentValue = $event.target.checked; this.$emit('input', this.currentValue); }})Copy the code

In Vue 2.2, you can customize Prop/Event in the form of model options when defining components.

4. Vue component data flow

Two-way data binding is to dynamically modify model and View by adding change(input) events to input elements (input, textare, etc.) on the basis of one-way binding. This is done by triggering ($emit) events from the parent component to modify the MV to achieve the MVVM effect. The child component can maintain its own data internally, but it has no right to modify the data passed to it by the parent component. When a developer tries to do so, VUE will report an error. This is done to better decoupling between components, there are probably more child components depend on the development of one of the parent component data, if child components can modify the parent component data, a child component change triggers all depend on the data of a component change, so the vue child components is not recommended to modify data of parent component, Modifying props directly raises a warning. The flow chart is as follows:

So, when you want to modify props in a child component, use that child component as the parent, so there it is

  • Define a local variable and initialize it with the value of prop.
  • Define a calculation property that handles the value of prop and returns it.