v-model 語法糖原理
元件直接加入 v-model
tags: vue
解析 v-model 背後都做了什麼
在 vue2.0 中 v-model 語法糖簡寫的程式碼:
<Son :value="msg" @input="msg=$event" />
在 vue3.0 中 v-model 語法糖有所調整:
<Son :modelValue="msg" @update:modelValue="msg=$event" />
寫一個案例來說明:
需求:父元件傳了一個值給子元件,子元件透過自訂事件去修改值並讓改過的值可以正確顯示
App 元件
vue
<template>
<div>
<h1>父元件 - {{ count }}</h1>
<hr />
<Son :modelValue="count" @update:modelValue="count = $event" />
</div>
</template>
<script>
import { ref } from 'vue'
import Son from './Son.vue'
export default {
name: 'App',
components: { Son },
setup() {
const count = ref(10)
return { count }
}
}
</script>
Son 元件
vue
<template>
<h2>
子元件 - {{ modelValue }}
<button @click="handleClick">改變父元件</button>
</h2>
</template>
<script>
export default {
name: 'Son',
props: {
modelValue: {
type: Number,
default: 0
}
},
setup(props, { emit }) {
const handleClick = () => {
emit('update:modelValue', 100)
}
return {
handleClick
}
}
}
</script>
首先要來理解一下這段程式碼的意義:@update:modelValue="count = $event"
, $event
此時為自訂事件的傳參,也就是子元件傳來的 100,然後將它賦值給了 count。
使用 v-model 簡化程式碼
在案例中的這一行程式碼:
vue
<Son :modelValue="count" @update:modelValue="count = $event" />
可以直接用 v-model 來完成一樣的功能
vue
<Son v-model="count" />
總結:
v2 對比 v3
vue3.0 封裝元件支持 v-model 的時候,父傳子:modelValue
子傳父 @update:modelValue
vue2.0 的 xxx.sync 語法糖解析:
- 父傳子
:xxx
子傳父@update:xxx
在vue3.0 使用v-model:xxx
代替。
補充:Vue 的 $event
如果想要獲取到原生事件裡的事件物件 (Event Object):
- 如果綁定的是函式 func
func(e){ // e 就是事件物件 }
- 如果綁定的是JS表達式,此時提供一個默認的變量
$event
例如我在 h1 上綁一個點擊事件並直接寫表達式:
vue
<h1 @click="$event.target.style.color = 'orange'">父元件 - {{ count }}</h1>
此時就能透過 $event.target 來取得觸發事件的元素進行操作
如果想要獲取自訂事件:
- 如果綁定的是函式 func
func(data) { // data 觸發自訂事件的傳參 }
- 如果綁定的是JS表達式,此時
$event
代表觸發自訂事件的傳參