iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0
Vue.js

Vue.js 新手入門之路系列 第 20

Vue.js 新手入門之路 - emit 事件

  • 分享至 

  • xImage
  •  

在元件中,我們可以使用 emit 的方式來實作,
子元件:

<script setup>
const emit = defineEmits(['someEvent'])

function handleClick() {
  emit('someEvent', 'Hello from child!')
}

const attr = 'box'
</script>

<template>
    <div :class="attr">
        <button @click="handleClick">Click Me (Child)</button>
    </div>
</template>

<style scoped>
.box{
  display: flex;
  text-align: center;
  justify-content: center;
  flex-direction: column;
  font-size: x-large;
  border: solid;
  margin-left: 450px;
  margin-top: 5px;
  height: 200px;
  width: 350px;
  padding: 35px;
}
</style>

父元件:

<script setup>
import MyButton from './components/emit.vue'

function onSomeEvent(message) {
  console.log('父組件收到事件:', message)
}
</script>

<template>
  <h2>觸發與監聽事件 Demo</h2>
  <!-- 監聽子元件事件 -->
  <MyButton @some-event="onSomeEvent" />
</template>

父元件監聽到子元件傳出來的參數 Hello from child!
https://ithelp.ithome.com.tw/upload/images/20250909/20178296zOSrd1zI4a.png

子元件傳不同參數

<script setup>
const emit = defineEmits(['increaseBy'])

function increase(n) {
  emit('increaseBy', n)
}
</script>

<template>
  <div :class='attr'>
    <button @click="increase(1)">+1</button>
    <button @click="increase(5)">+5</button>
    <button @click="increase(10)">+10</button>
  </div>
</template>


<style scoped>
.box{
  display: flex;
  text-align: center;
  justify-content: center;
  flex-direction: column;
  font-size: x-large;
  border: solid;
  margin-left: 450px;
  margin-top: 5px;
  height: 200px;
  width: 350px;
  padding: 35px;
}
</style>

父元件接收

<script setup>
import { ref } from 'vue'
import MyButton from './components/emit.vue'

const count = ref(0)

function increaseCount(n) {
  count.value += n
}
</script>

<template>
  <div>
    <p>目前 count: {{ count }}</p>
    <!-- 綁定 -->
    <MyButton @increase-by="increaseCount" />
    
  </div>
  
</template>

也可以用內聯的方式

<!-- 內聯函數 -->
    <MyButton @increase-by="(n) => count += n" />

https://ithelp.ithome.com.tw/upload/images/20250909/20178296c4WKxX5Ufh.png

emit 校驗

可以檢查該事件是否合法

<script setup>
const emit = defineEmits({
  submit: (payload) => {
    if (payload.email && payload.password) {
      return true
    } else {
      console.warn('Invalid submit event payload!', payload)
      return false
    }
  }
})

const attr = 'box'

function handleSubmit() {
  const email = 'user@test.com'
  const password = ''

  emit('submit', { email, password })
}
</script>

<template>
  <div :class="attr">
    <h3>子元件:LoginForm</h3>
    <button @click="handleSubmit">送出</button>
  </div>
</template>

<style scoped>
.box{
  display: flex;
  text-align: center;
  justify-content: center;
  flex-direction: column;
  font-size: x-large;
  border: solid;
  margin-left: 850px;
  height: 200px;
  width: 350px;
  padding: 35px;
}
</style>

這邊故意將 password 設定為空,console 會印出 invalid
https://ithelp.ithome.com.tw/upload/images/20250909/20178296CcKXSNxION.png

ref:
https://zh-hk.vuejs.org/guide/components/events.html


上一篇
Vue.js 新手入門之路 - props (二)
下一篇
Vue.js 新手入門之路 - fallthrough
系列文
Vue.js 新手入門之路25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言