iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0

前言:

上一章節提及到如何使用prop做組件之間的傳遞
但缺點在於這個方式對組件來說過於的複雜
複雜的組件結構, prop會需要多個函數調用才能達到傳遞的功能

本章節會使用Vue中的自定義事件達到組淺淺的傳遞
可以減少組件間函數大量調用的情形

事件綁定:

使用 prop傳遞配置是使用 v-bind對組件進行綁定
除了 data的傳遞外, method也可以順利傳遞
但除此之外 method可以用 v-on的方式綁定自定義的事件

範例:(App.vue)

<template>
  <div id="app">
		<text @demo="testFuction" />
	</div>
</template>
//...審略
methods : {
	testFuction(value) {
		console.log("接收到的資料:", value)
	}
}

上面的範例中是對 test組件綁定了一個事件 demo
他會去觸發 App.vue的 methods → testFunction(value)

事件觸發:

雖然綁定了一個自定義事件, 但使用該事件並非能直接取用
在 test組件中要有一個觸發該自定義事件的事件 (以 methods作範例)
範例:(test.vue)

<template>
  <div id="test">
		<input type="button" value="測試按鈕" @click="send" />
	</div>
</template>
//...審略
methods : {
	send() {
		this.$emit("demo", '測試資料')
	}
}

利用 Vue配置的屬性 $emit可以捕獲到要觸發的自定義事件
第一個參數即是綁定的事件名稱, 後續的參數就是給予預備呼叫的函數參數

事件綁定 (ref):

除此之外可以搭配 ref做事件綁定
其效果可以更彈性
ref → 在綁定組件標籤的時候可以取得該組件的實例對象
相對的取得該組件就可以綁定自定義事件
範例:(App.vue)

<template>
  <div id="app">
		<text ref="textComponent" />
	</div>
</template>
//...審略
methods : {
	testFuction(value) {
		console.log("接收到的資料:", value)
	}
},
mounted() {
	this.$refs.textComponent.$on("demo", this.testFunction)
}

$on其作用可以針對該實例對象綁定一個自定義事件
跟 v-on一樣是在 text組件上綁定一個 demo的自定義事件, 會觸發testFunction()
那寫在掛載完成後即是當組件掛載到真實 DOM的時候綁定事件
那針對彈性的部分在於搭配了 mounted, 讓綁定自定義事件可以畫面初始化的時候搭配
能配合定時器, 訂閱消息等等

事件解綁:

針對自定義事件一事, 其可以綁定, 當然也可以銷毀
銷毀的api → $off
在使用 $off的時候有3種情況

  1. 解綁單個事件:
    針對單一自定義事件的解綁很單純
this.$off("demo");
  1. 解綁多個事件:
    那針對多個自定義事件的解綁中
    並非傳多個參數就能解綁事件, 其必須搭配數組
this.$off(["demo1", "demo2"]); // O 正確
this.$off("demo1", "demo2"); // X 錯誤
  1. 解綁所有事件:
    那如果 $off中不帶參數的話, 其不會針對自定義事件解綁
    而是只要有自定義事件的存在
    就會將自定義事件解綁
    在使用上就要相對注意!!

  2. 組件銷毀時:
    在了解 Vue的生命週期的時候
    destroy相毀組件的時候, Vue會自動將所有的自定義事件解綁
    任何的自定義事件將全部銷毀


以上就是自定義事件的使用方式
比起用prop用函數的方式傳遞配置
自定義事件的彈性更佳的靈活
也變得不會太複雜
也搭配上Vue生命週期的規則

下一章節會提及如何將自定義事件放在原型對象中
並且說明其優勢在哪裡


上一篇
2023鐵人賽_Vue2基本使用規則(Day28)- PROP組件傳遞
下一篇
2023鐵人賽_Vue2基本使用規則(Day30)- 全局事件總線
系列文
Vue2 初步認識以及基本使用規則 && 了解 Vue2 的基本原理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言