Vue.js組件通信之自定義事件詳解
組件通信
從父組件向子組件通信,通過(guò)props傳遞數(shù)據(jù)就可以了,但Vue組件通信的場(chǎng)景不止有這一種,歸納起來(lái),組件之間的通信可以用下圖來(lái)表示:

自定義事件
當(dāng)子組件需要向父組件傳遞數(shù)據(jù)時(shí),就要用到自定義事件。子組件用**$ emit()來(lái)觸發(fā)事件**,父組件用**$ on()**來(lái)監(jiān)聽(tīng)子組件的事件。
父組件也可以直接在子組件的自定義標(biāo)簽上使用v-on來(lái)監(jiān)聽(tīng)子組件觸發(fā)的事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<title>自定義事件</title>
</head>
<body>
<div id="app">
<p>總數(shù):{{total}}</p>
<my-component
@increase="handleGetTotal"
@reduce="handleGetTotal"></my-component>
</div>
<script>
Vue.component('my-component',{
template: '\
<div>\
<button @click="handleIncrease">+1</button>\
<button @click="handleReduce">-1</button>\
</div>',
data: function () {
return {
counter: 0
}
},
methods: {
handleIncrease: function () {
this.counter++;
this.$emit('increase', this.counter);
},
handleReduce: function () {
this.counter--;
this.$emit('reduce', this.counter);
}
}
});
var app = new Vue({
el: '#app',
data: {
total: 0
},
methods: {
handleGetTotal: function (total) {
this.total = total;
}
}
});
</script>
</body>
</html>

子組件有兩個(gè)按鈕,分別實(shí)現(xiàn)+1和-1的效果,在改變組件的data “counter”后,通過(guò)$emit()在把它傳遞給父組件,父組件使用v-on:increase和v-on:reduce監(jiān)聽(tīng)事件。
$emit()方法的第一個(gè)參數(shù)是自定義事件的名稱(chēng),后面的參數(shù)是要傳遞的數(shù)據(jù),可以不填或者填寫(xiě)多個(gè)。
注意:除了用v-on在組件上監(jiān)聽(tīng)自定義事件外,也可以監(jiān)聽(tīng)DOM事件,這時(shí)候可以用 .native修飾符表示監(jiān)聽(tīng)的是一個(gè)原生事件,監(jiān)聽(tīng)的是該組件的根元素:
<my-component v-on:click.native="handleClick"></my-component>
使用v-model
Vue 2.x 可以在自定義組件上使用v-model指令。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<title>使用v-model</title>
</head>
<body>
<div id="app">
<p>總數(shù):{{total}}</p>
<my-component v-model="total"></my-component>
</div>
<script>
Vue.component('my-component',{
template: '<button @click="handleClick">+1</button>',
data: function () {
return {
counter: 0
}
},
methods: {
handleClick: function () {
this.counter++;
this.$emit('input',this.counter);
}
}
});
var app = new Vue({
el: '#app',
data: {
total: 0
}
});
</script>
</body>
</html>
仍然是點(diǎn)擊按鈕+1的效果,不過(guò)這次組件$emit()的事件是特殊的input,在使用組件的父級(jí),并沒(méi)有在<my-component>上使用@input=“handler”,而是使用了v-model板頂?shù)囊粋€(gè)數(shù)據(jù)total。這也可以稱(chēng)作是一個(gè)語(yǔ)法糖,因?yàn)樯厦娴氖纠梢蚤g接地用自定義事件來(lái)實(shí)現(xiàn):
<div id="myApp">
<p>總數(shù):{{total}}</p>
<my-component1 @input="handlegetTotal"></my-component1>
</div>
<script>
Vue.component('my-component1',{
template: '<button @click="handleClick">+1</button>',
data: function () {
return {
counter: 0
}
},
methods: {
handleClick: function () {
this.counter++;
this.$emit('input',this.counter);
}
}
});
var myApp = new Vue({
el: '#myApp',
data: {
total: 0
},
methods: {
handlegetTotal: function (value) {
this.total = value;
}
}
});
</script>
v-model還可以用來(lái)創(chuàng)建自定義的表單輸入組件,進(jìn)行數(shù)據(jù)雙向綁定:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<title>自定義表單輸入組件</title>
</head>
<body>
<div id="app">
<p>總數(shù):{{total}}</p>
<my-component v-model="total"></my-component>
<button @click="handleReduce">-1</button>
</div>
<script>
Vue.component('my-component',{
props: ['value'],
template: '<input :value="value" @input="updateValue">',
methods: {
updateValue: function (event) {
this.$emit('input', event.target.value);
}
}
});
var app = new Vue({
el: '#app',
data: {
total: 0
},
methods: {
handleReduce: function () {
this.total--;
}
}
});
</script>
</body>
</html>

注意:實(shí)現(xiàn)這樣一個(gè)具有雙向綁定的v-model組件要滿足下面的兩個(gè)要求:
- 接受一個(gè)value屬性
- 在有新的value時(shí)觸發(fā)input事件
更多教程點(diǎn)擊《Vue.js前端組件學(xué)習(xí)教程》,歡迎大家學(xué)習(xí)閱讀。
關(guān)于vue.js組件的教程,請(qǐng)大家點(diǎn)擊專(zhuān)題vue.js組件學(xué)習(xí)教程進(jìn)行學(xué)習(xí)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue3+TS實(shí)現(xiàn)數(shù)字滾動(dòng)效果CountTo組件
最近開(kāi)發(fā)有個(gè)需求需要酷炫的文字滾動(dòng)效果,發(fā)現(xiàn)vue2版本的CountTo組件不適用與Vue3,沒(méi)有輪子咋辦,那咱造一個(gè)唄,感興趣的小伙伴可以跟隨小編一起了解一下2022-11-11
axios?發(fā)?post?請(qǐng)求,后端接收不到參數(shù)的完美解決方案
這篇文章主要介紹了axios?發(fā)?post?請(qǐng)求,后端接收不到參數(shù)的解決方案,場(chǎng)景很簡(jiǎn)單,就是一個(gè)正常 axios post 請(qǐng)求,本文給大家分享問(wèn)題原因分析及解決方案需要的朋友可以參考下2022-12-12
vue常用事件v-on:click詳解事件對(duì)象,事件冒泡,事件默認(rèn)行為
這篇文章主要介紹了vue常用事件之v-on:click?以及事件對(duì)象,事件冒泡,事件默認(rèn)行為,其實(shí)v-on后面跟的不止是click事件也可以是其他的事件,用法均相似,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
vue 導(dǎo)航菜單刷新?tīng)顟B(tài)不消失,顯示對(duì)應(yīng)的路由界面操作
這篇文章主要介紹了vue 導(dǎo)航菜單刷新?tīng)顟B(tài)不消失,顯示對(duì)應(yīng)的路由界面操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
vue實(shí)現(xiàn)商城秒殺倒計(jì)時(shí)功能
這篇文章主要介紹了vue實(shí)現(xiàn)商城秒殺倒計(jì)時(shí)功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Vue3 Pinia獲取全局狀態(tài)變量的實(shí)現(xiàn)方式
這篇文章主要介紹了Vue3 Pinia獲取全局狀態(tài)變量的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
基于Vue3自定義實(shí)現(xiàn)圖片翻轉(zhuǎn)預(yù)覽功能
這篇文章主要為大家詳細(xì)介紹了如何基于Vue3自定義實(shí)現(xiàn)簡(jiǎn)單的圖片翻轉(zhuǎn)預(yù)覽功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,有需要的小伙伴可以參考一下2023-10-10
vue-baidu-map實(shí)現(xiàn)區(qū)域圈線和路徑的漸變色
這篇文章主要介紹了vue-baidu-map實(shí)現(xiàn)區(qū)域圈線和路徑的漸變色方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07

