從 Vue 3 開始,Vue 經過多次語法演進,到目前 Vue 3.2 所提供的 Script Setup 後,Vue 的寫法總算穩定下來,改用 defineEmits()
定義 Event,也是目前 Vue 官網範例的正式寫法,但還是有不少網路上範例或書籍用的是 Vue 3 早期寫法,雖然不再建議這樣寫,但還是得看得懂,並藉此了解 Vue 語法的演變軌跡。
Version
Vue 3.4
Event
<template>
<MyCounter :initialCount="count" @countChange="onCountChange" />
{{ count }}
</template>
<script setup>
import { ref } from 'vue'
import MyCounter from '@/components/MyCounter.vue'
let count = ref(0)
let onCountChange = (val) => (count.value = val)
</script>
- 自行定義
MyConter
,將資料傳進initialCount
prop,並接收 component 傳出的countChange
event
Event 類似 function 的回傳值,可將資料透過 event 從 component 傳出
Options API
MyCounter.vue
<template>
<div class="box">
<button @click="onClick">Inner +</button>
</div>
</template>
<script>
export default {
props: {
initialCount: Number
},
data: function () {
return {
count: this.initialCount
}
},
methods: {
onClick() {
this.count++
this.$emit('countChange', this.count)
}
}
}
</script>
<style scoped>
.box {
border-style: solid;
border-width: 2px;
border-color: red;
width: fit-content;
}
</style>
- Option API 呼叫 event
props
:在props
key 下定義 prop- 使用
this
存取 prop - 使用
this.$emit()
發出 event
Composition API
MyCounter.vue
<template>
<div class="box">
<button @click="onClick">Inner +</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
props: {
initialCount: Number
},
setup(props, { emit }) {
let count = ref(props.initialCount)
let onClick = () => {
count.value++
emit('countChange', count.value)
}
return {
count,
onClick
}
}
}
</script>
<style scoped>
.box {
border-style: solid;
border-width: 2px;
border-color: red;
width: fit-content;
}
</style>
- Vue 3.0 與 3.1 所使用語法
- Composition API 必須在
setup()
中組合
後才可使用,並透過props
Object 讀取 prop setup()
第二個參數為context
object,包含attrs
、slots
、emit
、與expose
四個 property,因為目前只使用到emit
,因此只解構出emit
- 使用
emit()
呼叫 event
Script Setup
MyCounter.vue
<template>
<div class="box">
<button @click="onClick">Inner +</button>
</div>
</template>
<script setup>
let props = defineProps({ initialCount: Number })
let emit = defineEmits(['countChange'])
let count = props.initialCount
let onClick = () => {
count++
emit('countChange', count)
}
</script>
<style scoped>
.box {
border-style: solid;
border-width: 2px;
border-color: red;
width: fit-content;
}
</style>
- 使用
defineEmits()
compiler macro 展開,回傳emit()
- 使用
emit()
呼叫 event
Conclusion
defineEmits()
只是 compiler macro,因此並不需要import