Vue2 v – in the model
Vue provides us with v-model instructions to implement bi-directional data binding. Bi-directional data binding means that data updates elements and data updates when elements are updated.
Let’s review the usage of Vue2:
<template>
<div id="app">
<input type="text" v-model="value">
<p>{{value}}</p>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
}
}
}
</script>
Copy the code
V-model is actually a syntactic sugar, essentially written as follows:
<input type="text" :value="value" @input="value=$event.target.value">
Copy the code
Use of forms
In addition to the input element, the other form elements, the V-Model, can be bidirectional data bound, but the data types are different.
Radio buttons
For input:radio, it is the same as input:text, passing a string value, but listening for change and modifying the HTML property checked
<div id="app">
<label>
apple <input type="radio" value="apple" v-model="picked">
</label>
<label>
orange <input type="radio" value="orange" v-model="picked">
</label>
<label>
banana <input type="radio" value="banana" v-model="picked">
</label>
</div>
Copy the code
Check box
Check boxes, like checkboxes, are internally listening for change events. But there are two cases of multiple checkboxes:
We can use a single check box to indicate select/deselect, or multiple check boxes to indicate which to select.
Single check box
Two-way data binding is accomplished by binding the V-Model to a Boolean value.
Multiple check boxes
Bind the V-Models of these check boxes to the same array. The value in the data is the selected value.
<div id="app"> <input type="checkbox" id="1" value="xxx" v-model="checked"> <label for="1">xxx</label> <input type="checkbox" id="2" value="yyy" v-model="checked"> <label for="2">yyy</label> <input type="checkbox" id="3" Value = "z" v - model = "checked" > < label for = "3" > z < / label > < br > < span > selected are: {{checked}} < / span > < / div >Copy the code
Others include select and Textarea. See the official documentation for form input bindings
Use of components
Not only form elements can be used, but components can also implement two-way data binding.
For example, there is a my-input component:
<template>
<div class="my-input">
:value="value" @input="$emit('input', $event.target.value)"
<p>value: {{ value }}</p>
</div>
</template>
<script>
export default {
props: ['value']
};
</script>
Copy the code
Then use it in app.vue:
<template> <div id="app"> <my-input v-model="value" /> </div> </template> <script> import MyInput from './components/MyInput' export default { components: { MyInput }, data() { return { value: "", }; }}; </script>Copy the code
Such V-models are still syntactically sugar, essentially doing what they bind to the value property and listen for input events:
<my-input :value="value" @input="value = $event" />
Copy the code
If we want to implement other forms of V-Model, we need to configure an option inside the component:
Prop represents the value of the external property bound when using the V-Model on the component, and Event represents the event to listen for (which can be a custom event)
model: {
prop: 'checked',
event: 'change'
},
Copy the code
The sync modifier
However, v-Model for components to achieve two-way data binding has a disadvantage, that is, only one data can be bound, not multiple two-way data binding.
Vue2 provides another way to implement bidirectional data binding, the SYNC modifier of V-bind.
For example, with the my-Input component’s bidirectional data binding, we only need to modify the code a little bit:
// App.vue
<my-input :value.sync="value" />
// MyInput.vue
<input type="text" :value="value" @input="$emit('update:value', $event.target.value)" />
Copy the code
In essence, what.sync does is listen for custom events for the update: bound property. The previous app. vue is equivalent to:
<my-input :value="value" @update:value="value = $event" />
Copy the code
Comparison of the two:
- Both are used to implement two-way data transfer, implemented by syntax sugar, and finally passed
prop
+The event
To get the job done. v-model
Only one two-way data gang binding can be implemented;.sync
Whenever two-way data transfer is required, it can be used.
Changes in Vue3
Vue2 is criticized for providing two bidirectional bindings: v-model and.sync. In Vue3, the.sync modifier is removed and only v-model is used for bidirectional binding.
In order to make v-Model better bidirectional binding for multiple attributes, Vue3 made the following changes:
- When used with custom components
v-model
Directive, the default property name of the binding is changed from the originalvalue
intomodelValue
, the event name is changed from the originalinput
intoupdate:modelValue
- Remove the
.sync
Modifier, whose original function is defined byv-model
Parameter substitution of model
Configuration removed- Allow customization
v-model
The modifier
Note that there is no change in using the V-Model for normal form elements, only two-way data binding for components, which is simply a combination of v-Model and.sync.
If you don’t understand, change the previous example to the version of Vue3:
// app. vue <my-input v-model="value" /> // equivalent to // <my-input V-model :modelValue="value" @update:modelValue="value = $event" /> // MyInput.vue <input type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />Copy the code
One might say what if I need to bind multiple data? Or if I don’t want to use the attribute name modelValue, then according to principle (point 2), use the parameter of V-model:
<my-input v-model:inpVal="value" />
<input type="text" :value="inpVal" @input="$emit('update:inpVal', $event.target.value)" />
Copy the code
Because of the second point, the third point comes naturally, and the Model configuration is no longer required. Fourth, Vue3 can be upgraded with custom attribute modifiers:
Here’s a picture to illustrate: If we use the V-Model attribute modifier, Vue will pass a modelModifiers inside the component in addition to the modelValue attribute, which is an object It contains all the attribute modifiers used by the V-Model.
If the V-Model uses parameters, that is, doesn’t use the default modelValue, another attribute passed about attribute Modifiers is called the parameter +Modifiers
Inside the component we can decide what to do with the xxxModifiers attribute passed in.
Let’s modify the previous example:
App.vue
<div id="app">
<my-input v-model:inpVal.trim="value" />
</div>
Copy the code
MyInput.vue
<template> <div class="my-input"> <input type="text" :value="inpVal" @input="handelInput" /> <p>value: {{ inpVal }}</p> </div> </template> <script> import { onMounted } from "vue"; export default { props: ["inpVal", "inpValModifiers"], setup(props, ctx) { const printModifiers = () => { console.log(props.inpValModifiers); }; const handelInput = (e) => { ctx.emit("update:inpVal", e.target.value); }; onMounted(printModifiers); return { printModifiers, handelInput }; }}; </script>Copy the code
Using the.trim custom modifier, we want to remove the leading and trailing whitespace:
const handelInput = (e) = > {
let val = e.target.value;
if(props.inpValModifiers? .trim) { val = val.trim(); } ctx.emit("update:inpVal", val);
};
Copy the code