v-model:雙數據綁定
一、v-model是一個語法糖
<template> <div id="app"> <input type="text" v-model="name"> <p>{{name}}</p> </div> </template> <script> export default { data() { return { name: '孫藝珍', age: 18 } } } </script>
以上代碼在運行時就可以達到雙數據綁定的效果:
v-model其實是 value 屬性和 input 事件的語法糖,什么意思呢?
如果把 v-model='name' 替換為 :value='name' @input="(e)=>name=e.target.value" 效果是一樣的
<template> <div id="app"> <!-- <input type="text" v-model="name"> --> <input type="text" :value='name' @input="(e)=>name=e.target.value"> <p>{{name}}</p> </div> </template>
就是說寫了v-model就相當於綁定了value屬性和input事件!
二、v-model可以給組件綁定數據
1、定義MyInput.vue組件:
<template> <div> <h1>自定義input</h1> <input type="text" :value="value" @input="(e)=>$emit('input',e.target.value)"> <p>{{value}}</p> </div> </template> <script> export default { props: ['value'] } </script>
2、App.vue中引入並使用
<template> <div id="app"> <input type="text" v-model="name"> <p>{{name}}</p> <MyInput v-model="name" /> </div> </template> <script> import MyInput from './components/MyInput' export default { data() { return { name: '孫藝珍', age: 18 } }, components: { MyInput } } </script>
此時,MyInput.vue中修改value會實時綁定到App.vue中的name
為什么MyInput.vue中props可以接收value,並且通過$emit觸發input事件呢?
因為 <MyInput v-model="name" /> 就相當於 <MyInput :value="name" @input="(val)=>name=val" />
v-model是value屬性和input事件的語法糖~
其中,@input="(val)=>name=val" 也可以寫成 @input="name=$event"
三、sync修飾符
如果需要給自定義組件綁定多個v-model,此時需要用到sync修飾符。
1、App.vue中將age傳遞給MyInput.vue
<MyInput v-model="name" :age.sync='age' />
2、MyInput.vue
<template> <div> <h1>自定義input</h1> <input type="text" :value="value" @input="(e)=>$emit('input',e.target.value)"> <p>{{value}}</p> <input type="text" :value="age" @input="(e)=>$emit('update:age',e.target.value)"> <p>{{age}}</p> </div> </template> <script> export default { props: ['value', 'age'] } </script>
注意:修改age時觸發的自定義事件為 update:age
既然用到了sync屬性,那么將v-model也改成sync的寫法,保持統一:
1、App.vue
<MyInput :name.sync='name' :age.sync='age' />
2、MyInput.vue
<template> <div> <h1>自定義input</h1> <input type="text" :value="name" @input="(e)=>$emit('update:name',e.target.value)"> <p>{{name}}</p> <input type="text" :value="age" @input="(e)=>$emit('update:age',e.target.value)"> <p>{{age}}</p> </div> </template> <script> export default { props: ['name', 'age'] } </script>
四、sync是一個語法糖
<MyInput v-model="name" :age.sync='age' />
為什么age屬性經過sync修飾后,修改age時觸發的事件名為 update:age ?
因為 :age.sync='age' 就是 :age='age' @update:age='age=$event' 的語法糖~
五、綁定對象內多個屬性,使用v-bind.sync='obj'
父組件:
<template> <div id="app"> <!-- <Child :name='name' @update:name='name=$event' /> <Child :name.sync='name' /> --> <Child :name='obj.name' @update:name='obj.name=$event' :age='obj.age' @update:age='obj.age=$event' /> <Child v-bind.sync='obj' /> </div> </template> <script> import Child from '@/components/Child' export default { data() { return { obj: { name: '小明', age: 28 } } }, components: { Child } } </script>
子組件:
<template> <div> <h1>姓名:{{name}}</h1> <h1>年齡:{{age}}</h1> <button @click="handleChangeName">改變姓名</button> <button @click="handleChangeAge">改變年齡</button> </div> </template> <script> export default { props: ['name', 'age'], methods: { handleChangeName() { this.$emit('update:name', '小紅') }, handleChangeAge() { this.$emit('update:age', 100) } } } </script>
六、vue3中v-model的使用
1、執行vue add vue-next將vue2升級到vue3
2、App.vue
<MyInput v-model:name="name" v-model:age="age" />
3、MyInput.vue
<template> <div> <h1>自定義input</h1> <input type="text" :value="name" @input="(e)=>$emit('update:name',e.target.value)" /> <p>{{name}}</p> <input type="text" :value="age" @input="(e)=>$emit('update:age',e.target.value)" /> <p>{{age}}</p> </div> </template> <script> export default { props: ['name', 'age'] } </script>
此時,就將App.vue中的name、age和MyInput.vue組件雙向綁定了