精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

快應(yīng)用的事件監(jiān)聽機(jī)制和組件間通信

開發(fā) 前端
前端的交互行為與事件機(jī)制息息相關(guān),對于前端開發(fā)者而言,掌握好事件機(jī)制是絕對必要的。

說起事件,做前端開發(fā)的朋友一定不會(huì)陌生。事件,即網(wǎng)頁上的一系列行為,可以是瀏覽器行為,如頁面完成了加載,頁面關(guān)閉;或是用戶操作行為,如用戶輸入操作,用戶點(diǎn)擊按鈕等,這些行為會(huì)被JavaScript監(jiān)測到,并執(zhí)行相應(yīng)的邏輯代碼。可以說,前端的交互行為與事件機(jī)制息息相關(guān),對于前端開發(fā)者而言,掌握好事件機(jī)制是絕對必要的。

所謂組件,即封裝起來的具有獨(dú)立功能的UI部件。試想,如果開發(fā)一個(gè)復(fù)雜的頁面,開發(fā)者把所有的UI部分寫在一個(gè)文件中,這樣的代碼顯然可維護(hù)性很低。但我們?nèi)绻媒M件的方式去重新思考UI構(gòu)成,將UI上每一個(gè)功能相對獨(dú)立的模塊定義成組件,然后將小的組件通過組合或者嵌套的方式構(gòu)成大的組件,進(jìn)而完成整體UI的開發(fā)。這樣,我們不僅提高了代碼的復(fù)用性,且整體結(jié)構(gòu)清晰,維護(hù)性則大大提高。

組件化界面

本文將介紹在快應(yīng)用開發(fā)中,事件相關(guān)的主要API以及事件的監(jiān)聽、觸發(fā)機(jī)制,同時(shí)會(huì)介紹快應(yīng)用中組件是如何通信的。閱讀本文前,建議先了解快應(yīng)用相關(guān)基礎(chǔ)知識(shí)。

自定義事件的監(jiān)聽、移除與觸發(fā)

$on 用于監(jiān)聽自定義事件;$off移除對應(yīng)的事件監(jiān)聽;$emit()、$dispatch()、 $broadcast()等方法可用于觸發(fā)事件。

$on(evtName, fnHandler)事件

在當(dāng)前頁面注冊監(jiān)聽事件, 可監(jiān)聽$emit()、 $dispatch()、 $broadcast()等觸發(fā)的自定義事件,不能用于注冊組件節(jié)點(diǎn)的事件響應(yīng)。

示例如下:

  1. export default {  
  2. onInit(){  
  3. this.$on('customEvtType1'this.customEvtType1Handler)  
  4. },  
  5. customEvtType1Handler(evt){  
  6. // 事件類型,事件參數(shù)  
  7. console.info(`觸發(fā)事件:類型:${evt.type}, 參數(shù): ${JSON.stringify(evt.detail)}`);  
  8.  

解釋一下

'customEvtType1'為該組件上自定義的事件名稱,customEvtType1Handler為當(dāng)'customEvtType1'事件被觸發(fā)時(shí),要執(zhí)行的回調(diào)函數(shù)。

$off(evtName, fnHandler)

移除事件監(jiān)聽,參數(shù) fnHandler 為可選,傳遞僅移除指定的響應(yīng)函數(shù),不傳遞則移除此事件的所有監(jiān)聽。

示例如下:

  1. export default {  
  2. removeEventHandler () {  
  3. // 不傳遞fnHandler:移除所有監(jiān)聽  
  4. this.$off('customEvtType1' 
  5. // 傳遞fnHandler:移除指定的監(jiān)聽函數(shù)  
  6. this.$off('customEvtType1'this.customEvtType1Handler)  
  7.  

頁面的交互中可能會(huì)遇到一些非手動(dòng)觸發(fā)的需求,$emit() 通過觸發(fā)當(dāng)前實(shí)例上的事件,達(dá)到動(dòng)態(tài)觸發(fā)事件的行為,類似jquery中的trigger方法。

$emit(evtName, evtDetail)

觸發(fā)當(dāng)前實(shí)例監(jiān)聽事件函數(shù),與 $on() 配合使用,注意:$emit() 目前只觸發(fā) $on 所監(jiān)聽的事件

示例如下:

  1. export default {  
  2. emitEvent () {  
  3. this.$emit('customEvtType1', { params: '參數(shù)內(nèi)容' })  
  4.  

監(jiān)聽原生組件事件

原生組件即框架自帶的組件,如div,text等等,其支持一系列事件,如通用事件(如:click, disappear)、組件專有事件(如:focus)。完整的原生組件列表以及事件可在快應(yīng)用官網(wǎng)查詢到。

開發(fā)者可以在事件回調(diào)函數(shù)中,獲取到當(dāng)前觸發(fā)組件的信息,并進(jìn)行進(jìn)一步的操作。

在響應(yīng)函數(shù)執(zhí)行時(shí)通過target獲取,如:onClickHandler

在響應(yīng)函數(shù)綁定時(shí)傳遞參數(shù),如:onClickHandler2

示例如下:

  1. <template 
  2. <div class="tutorial-page" 
  3. <text id="elNode1" item-flag="{{ argName + 1 }}" onclick = "onClickHandler">組件節(jié)點(diǎn)1</text>  
  4. <text id="elNode2" item-flag="{{ argName + 2 }}" onclick = "onClickHandler2('參數(shù)1', argName)">組件節(jié)點(diǎn)2</text>  
  5. </div> 
  6.  
  7. </template 
  8. <style lang="less" 
  9. .tutorial-page {  
  10. flex-direction: column;  
  11.  
  12. </style> 
  13.  
  14. <script>  
  15. export default {  
  16. data () {  
  17. return {  
  18. argName: '動(dòng)態(tài)參數(shù)'  
  19.  
  20. }, 
  21.  
  22. onClickHandler (evt) {  
  23. // 事件類型,參數(shù)詳情  
  24. console.info(`觸發(fā)事件:類型:${evt.type}, 詳情: ${JSON.stringify(evt.detail)}`);  
  25. if (evt.target) {  
  26. console.info(`觸發(fā)事件:節(jié)點(diǎn):${evt.target.id}, ${evt.target.attr.itemFlag}`)  
  27.  
  28. }, 
  29.  
  30. onClickHandler2 (arg1, arg2, evt) {  
  31. // 事件類型,事件參數(shù),target  
  32. console.info(`觸發(fā)事件:類型:${evt.type}, 參數(shù): ${arg1}, ${arg2}`);  
  33.  
  34.  
  35. </script> 

解釋一下

onClickHandler函數(shù)如果不傳參數(shù),默認(rèn)參數(shù)env即為當(dāng)前觸發(fā)組件的實(shí)例;若傳遞了參數(shù),如onClickHandler2,則參數(shù)安順序排列,env為***一個(gè)參數(shù)。

觸發(fā)原生組件事件

用戶可通過手動(dòng)操作觸發(fā)事件,如點(diǎn)擊事件等,除此之外,也可以在代碼中通過$emitElement()完成事件的動(dòng)態(tài)觸發(fā),類似上文自定義組件中的$emit()方法。

$emitElement(evtName, evtDetail, id)

可以觸發(fā)指定組件id的事件,通過evt.detail獲取傳遞的參數(shù);該方法僅用于原生組件,對自定義組件無效。

示例如下:

  1. <template 
  2. <div class="tutorial-page" 
  3. <text onclick="emitElement">觸發(fā)組件節(jié)點(diǎn)的事件:click</text>  
  4. <text id="elNode1" item-flag="{{ argName + 1 }}" onclick = "onClickHandler">組件節(jié)點(diǎn)1</text>  
  5. <text id="elNode2" item-flag="{{ argName + 2 }}" onclick = "onClickHandler2('參數(shù)1', argName)">組件節(jié)點(diǎn)2</text>  
  6. </div>  
  7. </template
  8.  
  9. <style lang="less" 
  10. .tutorial-page {  
  11. flex-direction: column;  
  12.  
  13. </style> 
  14.  
  15. <script>  
  16. export default {  
  17. data () {  
  18. return {  
  19. argName: '動(dòng)態(tài)參數(shù)'  
  20.  
  21. }, 
  22.  
  23. onClickHandler (evt) {  
  24. // 事件類型,參數(shù)詳情  
  25. console.info(`觸發(fā)事件:類型:${evt.type}, 詳情: ${JSON.stringify(evt.detail)}`);  
  26. if (evt.target) {  
  27. console.info(`觸發(fā)事件:節(jié)點(diǎn):${evt.target.id}, ${evt.target.attr.itemFlag}`)  
  28.  
  29. }, 
  30.  
  31. onClickHandler2 (arg1, arg2, evt) {  
  32. // 事件類型,事件參數(shù),target  
  33. console.info(`觸發(fā)事件:類型:${evt.type}, 參數(shù): ${arg1}, ${arg2}`);  
  34. }, 
  35.  
  36. emitElement () {  
  37. // 注意:通過此類方式的事件不會(huì)攜帶target屬性,開發(fā)者可以通過detail參數(shù)實(shí)現(xiàn)  
  38. this.$emitElement('click', { params: '參數(shù)內(nèi)容' }, 'elNode1' 
  39.  
  40.  
  41. </script> 

解釋一下

Click事件可通過用戶點(diǎn)擊操作觸發(fā),也可通過$emitElement觸發(fā)。

自定義組件

上文曾提到原生組件,通常原生組件是我們系統(tǒng)中最基礎(chǔ)的組件,然而我們在做一個(gè)稍微復(fù)雜的頁面時(shí),如果每個(gè)頁面都只用原生組件搭建,那這樣的代碼的可維護(hù)性會(huì)差很多。打個(gè)比方,就好比一個(gè)人口眾多的國家,沒有省、市、縣這些單位,而是只以個(gè)人為單位,難以想象這個(gè)國家的管理將有多難。道理類似,自定義組件,我們可以根據(jù)具體的業(yè)務(wù)邏輯,把頁面按照功能拆成多個(gè)模塊,每個(gè)模塊負(fù)責(zé)其中的一個(gè)功能部分,***頁面將由這些模塊組合搭建起來,讓代碼結(jié)構(gòu)更加清晰,易于維護(hù)。

自定義組件是開發(fā)者編寫的組件,使用起來和Native原生組件一樣,最終按照組件的<template>來渲染;同時(shí)開發(fā)起來又和頁面一樣,擁有ViewModel實(shí)現(xiàn)對數(shù)據(jù)、事件、方法的管理,這么來看,頁面也是一種特殊的自定義組件,無需引入即可使用,同時(shí)服務(wù)于整個(gè)頁面。

編寫自定義組件

示例如下:

  1. <template 
  2. <div class="tutorial-page" 
  3. <text class="tutorial-title">自定義組件:</text>  
  4. <text>{{ prop1 }}</text>  
  5. <text>{{ prop2Object.name }}</text>  
  6. </div> 
  7.  
  8. </template 
  9. <style lang="less" 
  10. .tutorial-page {  
  11. flex-direction: column;  
  12. padding-top: 20px;  
  13. .tutorial-title {  
  14. font-weight: bold;  
  15.  
  16.  
  17. </style> 
  18.  
  19. <script>  
  20. // 子組件  
  21. export default {  
  22. props: [  
  23. 'prop1' 
  24. 'prop2Object'  
  25. ], 
  26.  
  27. data: {  
  28. }, 
  29.  
  30. onInit () {  
  31. console.info(`外部傳遞的數(shù)據(jù):`, this.prop1, this.prop2Object)  
  32.  
  33.  
  34. </script> 

兩點(diǎn)注意

一是自定義組件比頁面組件的不同之處在于多了一個(gè)props屬性,用于聲明該組件可接受的外部數(shù)據(jù)傳遞;props是一個(gè)數(shù)組,數(shù)組中每個(gè)元素是暴露的屬性。

二是如果屬性名稱使用駝峰定義,如:prop2Object,那么在外部傳遞數(shù)據(jù)時(shí)請使用-連接,如:prop2-object

引入自定義組件

引入自定義組件的方式和我們平時(shí)常用的方式不同,我們平時(shí)通常會(huì)用require或import的方式引入組件,而在快應(yīng)用框架中,需要使用<import>標(biāo)簽來引入。

示例如下:

  1. <import name="comp-part1" src="./part1"></import>  

<import>標(biāo)簽中的的src屬性指定自定義組件的地址,name屬性指定在<template>組件中引用該組件時(shí)使用的標(biāo)簽名稱

最終頁面定義與引入方式如下:

  1. <import name="comp-part1" src="./part1"></import
  2.  
  3. <template> 
  4.  
  5. <div class="tutorial-page"
  6.  
  7. <text class="tutorial-title">頁面組件:</text> 
  8.  
  9. <text>{{ data1 }}</text> 
  10.  
  11. <text>{{ data2.name }}</text> 
  12.  
  13. <text onclick="evtType1Emit">觸發(fā)$broadcast()</text> 
  14.  
  15. <comp-part1 prop1="{{data1}}" prop2-object="{{data2}}" onevt-type3="evtTypeHandler"></comp-part1> 
  16.  
  17. </div> 
  18.  
  19. </template> 
  20.  
  21. <style lang="less"
  22.  
  23. .tutorial-page { 
  24.  
  25. flex-direction: column; 
  26.  
  27. padding: 20px 10px; 
  28.  
  29. .tutorial-title { 
  30.  
  31. font-weight: bold; 
  32.  
  33.  
  34.  
  35. </style> 
  36.  
  37. <script> 
  38.  
  39. // 父組件 
  40.  
  41. export default { 
  42.  
  43. data: { 
  44.  
  45. data1: '傳遞字符串'
  46.  
  47. data2: { 
  48.  
  49. name: '傳遞對象' 
  50.  
  51.  
  52. }, 
  53.  
  54. onInit () { 
  55.  
  56. this.$page.setTitleBar({ text: '父子組件通信' }) 
  57.  
  58. this.$on('evtType2'this.evtTypeHandler) 
  59.  
  60. }, 
  61.  
  62. evtTypeHandler (evt) { 
  63.  
  64. console.info(`父組件:事件響應(yīng): `, evt.type, evt.detail) 
  65.  
  66. // 結(jié)束事件傳遞 
  67.  
  68. // evt.stop() 
  69.  
  70. }, 
  71.  
  72. evtType1Emit () { 
  73.  
  74. this.$broadcast('evtType1', { params: '額外參數(shù)' }) 
  75.  
  76.  
  77.  
  78. </script> 

解釋一下

上面的代碼中有幾點(diǎn)需要說明:

1 在comp-part1標(biāo)簽中,我們看到這樣一個(gè)屬性,onevt-type3="evtTypeHandler",這是指,在該節(jié)點(diǎn)上綁定了名為evtType3的方法,被觸發(fā)后,執(zhí)行evtTypeHandler的函數(shù),在下文的‘父子之間組件事件傳遞’中,會(huì)看到如何觸發(fā)該方法。

2 代碼中的evtType1Emit方法,該方法通過調(diào)用$broadcast方法,觸發(fā)了名為'evtType1'的事件,并傳遞了params參數(shù),'evtType1'事件也可以在下文‘父子組件之間事件傳遞’中看到。

傳遞數(shù)據(jù)與數(shù)據(jù)改造

如上面所述,父組件向子組件傳遞數(shù)據(jù),通過在子組件的props屬性中聲明對外暴露的屬性名稱,然后在組件引用標(biāo)簽上聲明傳遞的父組件數(shù)據(jù)。

如果你需要在子組件中對數(shù)據(jù)進(jìn)行改造,但又不想改動(dòng)父組件數(shù)據(jù)時(shí),可以使用$watch()來滿足需求。如果是監(jiān)聽對象中的屬性,參數(shù)請使用.分割,如:$watch(xxx.xxx.xxx, methodName)

示例如下:

  1. <script>  
  2.   
  3. // 子組件  
  4.   
  5. export default {  
  6.   
  7. props: [  
  8.   
  9. 'prop1',  
  10.   
  11. 'prop2Object'  
  12.   
  13. ],  
  14.   
  15. data () {  
  16.   
  17. return {  
  18.   
  19. upperProp1: this.prop1  
  20.   
  21. }  
  22.   
  23. },  
  24.   
  25. onInit () {  
  26.   
  27. console.info(`外部傳遞的數(shù)據(jù):`, this.prop1, this.prop2Object)  
  28.   
  29. // 監(jiān)聽數(shù)據(jù)變化  
  30.   
  31. this.$watch('prop1''watchPropsChange')  
  32.   
  33. this.$watch('prop2Object.name''watchPropsChange')  
  34.   
  35. },  
  36.   
  37. /**  
  38.   
  39. * 監(jiān)聽數(shù)據(jù)變化,你可以對數(shù)據(jù)處理后,設(shè)置值到data上  
  40.   
  41. * @param newV  
  42.   
  43. * @param oldV  
  44.   
  45. */  
  46.   
  47. watchPropsChange (newV, oldV) {  
  48.   
  49. console.info(`監(jiān)聽數(shù)據(jù)變化:`, newV, oldV)  
  50.   
  51. this.upperProp1 = newV && newV.toUpperCase()  
  52.   
  53. }  
  54.   
  55. }  
  56.   
  57. </script>  

解釋一下

上面是子組件的代碼,我們看到data中定義了upperProp1,同時(shí)也看到watchPropsChange方法中,有兩個(gè)參數(shù),一個(gè)是newV,指變化后的屬性值,oldV指原先的屬性值,將newV賦值給upperProp1,這樣在子組件中對數(shù)據(jù)upperProp1進(jìn)行改造,就不會(huì)改動(dòng)父組件原先的數(shù)據(jù)。

父子組件之間的事件傳遞

當(dāng)子組件對數(shù)據(jù)進(jìn)行改造后,把最終數(shù)據(jù)交給父組件甚至往上,往往有兩種辦法

1、父組件傳遞的數(shù)據(jù)本身就是對象,子組件直接修改的就是這個(gè)對象中的屬性;那么父組件同樣也就拿到了最終數(shù)據(jù)

2、子組件在data中保存了一份內(nèi)部數(shù)據(jù),需要交給父組件:子組件通過$dispatch()完成事件觸發(fā),父組件通過$on()綁定事件并響應(yīng),如:evtType2;

類似于2,子組件在data中保存了一份內(nèi)部數(shù)據(jù),需要交給父組件:子組件通過$emit()觸發(fā)在節(jié)點(diǎn)上綁定的事件來執(zhí)行父組件的方法,如:evtType3;

示例如下:

  1. <script>  
  2.   
  3. // 子組件  
  4.   
  5. export default {  
  6.   
  7. props: [  
  8.   
  9. 'prop1',  
  10.   
  11. 'prop2Object'  
  12.   
  13. ],  
  14.   
  15. data () {  
  16.   
  17. return {  
  18.   
  19. upperProp1: this.prop1  
  20.   
  21. }  
  22.   
  23. },  
  24.   
  25. onInit () {  
  26.   
  27. console.info(`外部傳遞的數(shù)據(jù):`, this.prop1, this.prop2Object)  
  28.   
  29. // 綁定VM的自定義事件  
  30.   
  31. this.$on('evtType1'this.evtTypeHandler)  
  32.   
  33. // 這里我認(rèn)為官網(wǎng)的代碼示例存在問題,因此注釋掉了,此處應(yīng)該將其移至父組件的onInit方法中。  
  34.   
  35. //this.$on('evtType2', this.evtTypeHandler)  
  36.   
  37. },  
  38.   
  39. evtTypeHandler (evt) {  
  40.   
  41. console.info(`子組件:事件響應(yīng): `, evt.type, evt.detail)  
  42.   
  43. // 結(jié)束事件傳遞  
  44.   
  45. // evt.stop()  
  46.   
  47. },  
  48.   
  49. evtType2Emit () {  
  50.   
  51. this.$dispatch('evtType2', { params: '額外參數(shù)' })  
  52.   
  53. },  
  54.   
  55. evtType3Emit () {  
  56.   
  57. this.$emit('evtType3', { params: '額外參數(shù)' })  
  58.   
  59. }  
  60.   
  61. }  
  62.   
  63. </script>  

解釋一下

在上文我已做了如下說明

1 在父組件的comp-part1標(biāo)簽中,我們看到這樣一個(gè)屬性,onevt-type3 = "evtTypeHandler",這是指,在該節(jié)點(diǎn)上綁定了名為evtType3的方法,如果子組件中evtType3Emit調(diào)用執(zhí)行,則會(huì)執(zhí)行父組件中的evtTypeHandler的函數(shù), 從而完成子組件與父組件的通信。

2 父組件中的evtType1Emit方法,該方法通過調(diào)用$broadcast方法,觸發(fā)了名為'evtType1'的事件,并傳遞了params參數(shù),'evtType1'事件則注冊在子組件的onInit方法中,從而完成父組件與子組件的通信。

所以,框架向開發(fā)者提供了雙向的事件傳遞。

向下傳遞:父組件觸發(fā),子組件響應(yīng);調(diào)用parentVm.$broadcast()完成向下傳遞,如:evtType1

向上傳遞:子組件觸發(fā),父組件響應(yīng);調(diào)用childVm.$dispath()完成向上傳遞,如:evtType2

兄弟組件之間的通信

傳統(tǒng)的兄弟等非父子組件之間通信,是通過觀察者模型來完成。觀察者模式的作用是當(dāng)一個(gè)對象的狀態(tài)發(fā)生變化時(shí),能夠自動(dòng)通知其他關(guān)聯(lián)對象,自動(dòng)刷新對象狀態(tài)。

開發(fā)者可以自己寫一個(gè)Pub/Sub模型實(shí)現(xiàn)通信解耦;不過本文并不詳細(xì)介紹如何通過觀察者模式來實(shí)現(xiàn)組件間通信,這個(gè)題目夠另寫一篇文章了。

其實(shí),在業(yè)務(wù)邏輯相對簡單的情況下,我們可以使用ViewModel本身的事件綁定來處理。兄弟組件的相同點(diǎn)是,他們擁有相同的父組件,所以,父組件將是兄弟組件通信的橋梁,可以在以下代碼中看到這個(gè)過程。

示例如下:

子組件定義了Sub端的邏輯處理,有processMessage()、customEventInVm2(),后者同使用$on效果一致

  1. <template>  
  2.   
  3. <div class="tutorial-page">  
  4.   
  5. <text class="tutorial-title">自定義組件2:</text>  
  6.   
  7. <text>處理消息:{{msg}}</text>  
  8.   
  9. <text>事件內(nèi)容:{{eventDetail}}</text>  
  10.   
  11. </div>  
  12.   
  13. </template>  
  14.   
  15. <style lang="less">  
  16.   
  17. </style>  
  18.   
  19. <script>  
  20.   
  21. // 子組件: part2  
  22.   
  23. export default {  
  24.   
  25. props: [  
  26.   
  27. ],  
  28.   
  29. data () {  
  30.   
  31. return {  
  32.   
  33. msg: null,  
  34.   
  35. eventDetail: null  
  36.   
  37. }  
  38.   
  39. },  
  40.   
  41. processMessage (msg) {  
  42.   
  43. const now = (new Date).toISOString()  
  44.   
  45. this.msg = `${now}: ${msg}`  
  46.   
  47. },  
  48.   
  49. /**  
  50.   
  51. * 通過events對象:綁定事件,和on效果一致  
  52.   
  53. */  
  54.   
  55. events: {  
  56.   
  57. customEventInVm2 (evt) {  
  58.   
  59. const now = (new Date).toISOString()  
  60.   
  61. this.eventDetail = `${now}: ${evt.detail}`  
  62.   
  63. }  
  64.   
  65. }  
  66.   
  67. }  
  68.   
  69. </script>  

另外一個(gè)兄弟組件可以通過父組件中建立相互引用達(dá)到相互持有ViewModel的目的,通過在生命周期onReady()中執(zhí)行establishRef()實(shí)現(xiàn),如下代碼所示:

  1. <template>  
  2.   
  3. <div class="tutorial-page">  
  4.   
  5. <!-- 兄弟VM通信 -->  
  6.   
  7. <comp-part2 id="sibling1"></comp-part2>  
  8.   
  9. <comp-part3 id="sibling2"></comp-part3>  
  10.   
  11. </div>  
  12.   
  13. </template>  
  14.   
  15. <style lang="less">  
  16.   
  17. </style>  
  18.   
  19. <script>  
  20.   
  21. // 父組件  
  22.   
  23. export default {  
  24.   
  25. onReady () {  
  26.   
  27. this.establishRef()  
  28.   
  29. },  
  30.   
  31. /**  
  32.   
  33. * 建立相互VM的引用,父組件將兩個(gè)兄弟組件聯(lián)系了起來  
  34.   
  35. */  
  36.   
  37. establishRef () {  
  38.   
  39. const siblingVm1 = this.$vm('sibling1')  
  40.   
  41. const siblingVm2 = this.$vm('sibling2')  
  42.   
  43. siblingVm1.parentVm = this  
  44.   
  45. siblingVm1.nextVm = siblingVm2  
  46.   
  47. siblingVm2.parentVm = this  
  48.   
  49. siblingVm2.previousVm = siblingVm1  
  50.   
  51. }  
  52.   
  53. }  
  54.   
  55. </script>  

那么另外一個(gè)子組件的Pub端定義就很簡單了,執(zhí)行sendMesssage()即可完成觸發(fā),如下代碼所示:

  1. <template>  
  2.   
  3. <div class="tutorial-page">  
  4.   
  5. <text class="tutorial-title">自定義組件3:</text>  
  6.   
  7. <text onclick="sendMesssage">點(diǎn)擊發(fā)送消息</text>  
  8.   
  9. </div>  
  10.   
  11. </template>  
  12.   
  13. <style lang="less">  
  14.   
  15. </style>  
  16.   
  17. <script>  
  18.   
  19. // 子組件: part3  
  20.   
  21. export default {  
  22.   
  23. sendMesssage () {  
  24.   
  25. if (this.previousVm) {  
  26.   
  27. // Way1. 調(diào)用方法  
  28.   
  29. this.previousVm.processMessage('兄弟之間通信的消息內(nèi)容')  
  30.   
  31. // Way2. 觸發(fā)事件  
  32.   
  33. this.previousVm.$emit('customEventInVm2''兄弟之間通信的消息內(nèi)容')  
  34.   
  35. }  
  36.   
  37. }  
  38.   
  39. }  
  40.   
  41. </script>  

解釋一下

通過上面的例子,我們可以看到,comp-part2和 comp-part3在父組件中通過nextVm和previousVm建立了‘兄弟關(guān)系’,基于此,它們之間可以直接調(diào)用對方的方法(如processMessage),或會(huì)通過$emit方法觸發(fā)對方監(jiān)聽的事件'customEventInVm2'

結(jié)尾

本文對快應(yīng)用開發(fā)中的事件監(jiān)聽以及觸發(fā)方式做了介紹,通過學(xué)習(xí)我們能夠更好的分離業(yè)務(wù)邏輯,減少方法響應(yīng)上的耦合。另外,通過掌握自定義組件的開發(fā),會(huì)讓我們的項(xiàng)目結(jié)構(gòu)更加明朗,更易于維護(hù);同時(shí)了解父子、兄弟組件之間的數(shù)據(jù)通信,更是完成好快應(yīng)用開發(fā)的必要條件。當(dāng)然,本文多數(shù)素材來源于官方文檔中的示例,但對其中模糊之處做了相應(yīng)解釋和補(bǔ)充,希望能夠給讀者些許幫助。如有不足之處,歡迎指正。

 

 

責(zé)任編輯:張燕妮 來源: 51CTO
相關(guān)推薦

2010-07-29 10:33:59

Flex鍵盤事件

2010-08-06 10:03:42

Flex事件

2019-11-04 11:06:36

kubernetes通信組件

2024-01-09 08:34:56

Vue3.js組件通信

2023-11-02 08:10:13

框架Spring程序事件

2010-08-09 09:47:34

Flex事件機(jī)制

2015-09-11 09:15:32

RyuSDN

2021-08-03 12:47:58

鴻蒙HarmonyOS應(yīng)用

2025-03-04 08:56:31

2025-03-11 00:35:00

Spring事件機(jī)制

2010-08-09 11:06:01

Flex事件機(jī)制

2020-05-27 20:25:47

SpringSpringBoot數(shù)據(jù)

2023-01-05 07:39:28

2023-09-28 08:00:53

2020-01-16 11:23:32

Zookeeper數(shù)據(jù)結(jié)構(gòu)API

2022-07-27 08:40:06

父子組件VUE3

2023-09-27 07:13:59

Spring框架通信

2019-06-04 09:00:00

Linux進(jìn)程進(jìn)程間通信

2017-08-06 00:05:18

進(jìn)程通信開發(fā)

2019-05-15 08:00:00

vue組件間通信前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

日韩电影在线一区二区| 私拍精品福利视频在线一区| 日韩美女精品在线| aa日韩免费精品视频一| 精品亚洲永久免费| 亚洲成a人片77777在线播放| 欧美日韩一级大片网址| 欧美在线观看黄| 免费在线超碰| 国产精品69毛片高清亚洲| 精品少妇v888av| 扒开jk护士狂揉免费| 日韩成人在线一区| 大荫蒂欧美视频另类xxxx| 国产免费色视频| 午夜视频在线播放| 国产精品一区二区果冻传媒| 国产不卡在线观看| 久久高清无码视频| 日韩激情一区| 亚洲欧美国产日韩天堂区| 日韩av片免费观看| 日韩毛片免费观看| 亚洲第一av色| 亚洲色婷婷久久精品av蜜桃| 超碰免费在线| 91在线视频免费91| 99porn视频在线| 91午夜交换视频| 久久天堂精品| 8x拔播拔播x8国产精品| 欧美激情图片小说| 天天综合网91| 中文字幕九色91在线| 欧美做受喷浆在线观看| 粉嫩的18在线观看极品精品| 9191久久久久久久久久久| 蜜臀av午夜一区二区三区| 欧美24videosex性欧美| 日韩理论片中文av| 亚洲草草视频| 粉嫩av一区| 久久久久国产精品人| 国产欧美日韩一区二区三区| www.国产黄色| 国产麻豆欧美日韩一区| 国产中文欧美精品| 在线观看中文字幕码| 日韩 欧美一区二区三区| 日韩av黄色在线观看| 精品91久久久| 一本色道久久综合亚洲精品不卡| 欧美日本黄视频| 波多野结衣亚洲色图| 在线成人直播| 欧美另类精品xxxx孕妇| 欧美精品videos极品| 欧美 日韩 国产一区二区在线视频| 日韩在线观看网址| 欧美特黄一级片| 久久久久久久久久久9不雅视频| 中文字幕亚洲欧美日韩在线不卡| 91精品久久久久久久久久久久| 久久99蜜桃| 亚洲深夜福利网站| wwwww黄色| 国产精品99久久| 久久香蕉国产线看观看av| 日本午夜在线观看| 欧美ab在线视频| 91av国产在线| 91黑人精品一区二区三区| 日本强好片久久久久久aaa| 国产日韩精品视频| 丰满人妻一区二区三区免费视频 | 国产精品亚洲片夜色在线| 波多野结衣家庭主妇| 免费观看30秒视频久久| 亚洲自拍偷拍一区| 天天操天天干天天| 欧美极品美女视频| 午夜啪啪福利视频| 国产福利电影在线播放| 在线精品视频小说1| 一道本在线免费视频| 午夜视频一区二区在线观看| 亚洲第一天堂无码专区| 国产成人精品无码免费看夜聊软件| 精品视频黄色| 九九久久精品一区| 国产又黄又爽又色| 激情五月婷婷综合网| 国产精品自拍首页| 91精品国产综合久久久久久豆腐| 亚洲精选视频在线| 超碰网在线观看| 国产精品毛片无码| 亚洲免费av电影| 人妻人人澡人人添人人爽| 99精品99| 成人在线中文字幕| 色中色在线视频| 亚洲女爱视频在线| 三级4级全黄60分钟| 国产一区二区三区亚洲综合 | 最近中文字幕无免费| 精品高清在线| 国内精品模特av私拍在线观看| 中文字幕一区二区人妻痴汉电车| 成人免费va视频| 亚洲最新在线| 自拍偷拍亚洲视频| 精品成人一区二区| 男女全黄做爰文章| 日韩精品电影一区亚洲| 成人av电影免费| 黄色在线免费网站| 欧美综合视频在线观看| 特级西西人体4444xxxx| 亚洲私拍自拍| 3d精品h动漫啪啪一区二区| 91在线免费看| 一本到三区不卡视频| 黄色激情在线观看| 欧美va天堂在线| 91人成网站www| av资源在线观看免费高清| 欧美午夜丰满在线18影院| 日韩高清一二三区| 影音先锋成人在线电影| 国产欧美日韩视频| av在线天堂播放| 一本色道久久加勒比精品| 亚洲调教欧美在线| 9久re热视频在线精品| 99re在线观看| 午夜小视频福利在线观看| 91麻豆精品国产91久久久使用方法 | ass精品国模裸体欣赏pics| 亚洲欧美亚洲| 91精品免费| h网站久久久| 欧美美女激情18p| 亚洲少妇xxx| 精品影视av免费| 中国成人在线视频| 四虎国产精品永久在线国在线| 国产一区二区激情| 国产乱码77777777| 国产亚洲精久久久久久| 99久久激情视频| heyzo久久| 成人xxxx视频| 在线免费观看a视频| 日韩欧美一区二区在线视频| 69av视频在线| 成人在线视频一区二区| 五月丁香综合缴情六月小说| 国内视频在线精品| 欧美极品第一页| 亚洲人妻一区二区三区| 欧美网站在线观看| 国产又黄又粗视频| 久久成人麻豆午夜电影| 日韩中文在线字幕| 国产福利资源一区| 欧美在线观看网站| aaa在线免费观看| 日韩午夜激情av| 国产在线观看免费av| 91年精品国产| 亚洲一区二区三区观看| 国产综合欧美| 欧美日本国产精品| 日韩电影精品| 68精品久久久久久欧美| 黄色片在线播放| 91精品国产免费| 国产第一页第二页| 久久久99免费| 北条麻妃亚洲一区| 99伊人成综合| 国产高清精品软男同| 国产一区在线电影| 国产精品色婷婷视频| 欧美高清另类hdvideosexjaⅴ| 日韩大片在线观看视频| 亚洲系列在线观看| 亚洲成人精品一区| jizzjizzjizz国产| 99视频国产精品| 爱爱爱爱免费视频| 国产色综合网| 欧美日韩亚洲国产成人| 婷婷精品在线观看| 成人日韩av在线| 免费h在线看| 美女999久久久精品视频| 日韩精品视频无播放器在线看 | 成人免费大片黄在线播放| 99在线视频影院| 一区二区福利视频| 丰满少妇被猛烈进入| 欧美三级在线播放| 日本一级黄色大片| 18欧美乱大交hd1984| 加勒比一区二区| 成人精品高清在线| 日韩av卡一卡二| 玖玖精品视频| 缅甸午夜性猛交xxxx| 国产精品毛片久久| 日本高清不卡一区二区三| 综合激情五月婷婷| 国产一区玩具在线观看| 91精品韩国| 97av在线视频免费播放| a在线免费观看| 最近的2019中文字幕免费一页| 午夜av免费在线观看| 日韩一二三四区| 国产精品久久久久久免费播放| 色就色 综合激情| 亚洲精品在线观看av| 一级日本不卡的影视| 登山的目的在线| 国产欧美精品一区二区色综合朱莉 | 欧美精品在欧美一区二区| 99久久99热这里只有精品| 色一情一区二区三区四区| 老司机凹凸av亚洲导航| 粉嫩av免费一区二区三区| 91麻豆精品国产综合久久久| 国产精品尤物福利片在线观看| 姬川优奈av一区二区在线电影| 浅井舞香一区二区| 天堂8中文在线最新版在线| 午夜精品三级视频福利| 国精产品一区一区三区mba下载| 久久精品91久久久久久再现| 巨大荫蒂视频欧美大片| 久久精品国产一区| 激情在线小视频| 久久躁狠狠躁夜夜爽| jizzjizz亚洲| 久久久人成影片一区二区三区| 国产成人久久久| 日本蜜桃在线观看| 色噜噜久久综合伊人一本| 午夜视频成人| 久久久精品中文字幕| 黄在线免费看| 欧美高清激情视频| 国产777精品精品热热热一区二区| 欧美疯狂xxxx大交乱88av| 毛片大全在线观看| 欧美极品在线播放| 中文字幕影音在线| 国产精品偷伦一区二区| 欧美综合影院| 91在线在线观看| 精品国产一区二区三区不卡蜜臂| 国内一区二区三区在线视频| 香蕉视频一区| 涩涩涩999| 一本到12不卡视频在线dvd| www.夜夜爱| 国产精品毛片在线| 日韩大片一区二区| 国产九九视频一区二区三区| 成人区人妻精品一区二| 久久久久久久久久久久久夜| 国产123在线| 亚洲精品视频自拍| www.日本精品| 欧美视频在线播放| 99免费在线视频| 日韩国产中文字幕| 麻豆视频免费在线观看| 国a精品视频大全| 3d性欧美动漫精品xxxx软件| 91人成网站www| 亚洲综合小说图片| 国产91av视频在线观看| 激情久久五月| 日韩av卡一卡二| av亚洲精华国产精华精| 国精产品一区一区| 亚洲成在人线免费| 精品国产www| 亚洲第一精品夜夜躁人人爽 | 99视频精品在线| 欧美成人久久久免费播放| 午夜精品一区二区三区免费视频| 亚洲免费视频二区| 亚洲国产美女久久久久| 九七电影韩国女主播在线观看| 555www成人网| 日韩综合一区二区三区| 日本一区精品| 亚洲激情精品| 久久久精品视频国产| 国产欧美视频一区二区三区| 国产亚洲成人av| 欧美日韩不卡一区| 男女网站在线观看| 欧美激情亚洲另类| 精品国产美女a久久9999| 久久66热这里只有精品| 中文字幕人成人乱码| 日韩亚洲在线视频| 99精品热视频| 欧美精品xxxxx| 91麻豆精品国产91久久久| 毛片在线免费| 97视频在线观看亚洲| 欧美高清一级片| 亚洲欧美日韩国产成人综合一二三区| 国产一区二区三区成人欧美日韩在线观看| 宇都宫紫苑在线播放| 国产精品你懂的| 97人妻一区二区精品视频| 亚洲国产精品女人久久久| 免费毛片在线看片免费丝瓜视频| 成人免费观看a| 99久久这里只有精品| 国产又粗又长又大的视频| 久久一二三国产| 日韩一区二区视频在线| 亚洲第一福利网站| √天堂8资源中文在线| 高清视频在线观看一区| 欧美精品播放| 国产sm在线观看| 亚洲另类色综合网站| 国产情侣av在线| 伦理中文字幕亚洲| 国产精品视频一区视频二区| 成年人黄色在线观看| 久久成人羞羞网站| 天天色影综合网| 欧美一区国产二区| 在线观看免费视频你懂的| 亚洲影院色在线观看免费| 仙踪林久久久久久久999| 6080国产精品| 亚洲综合久久av| 亚洲精品一区二区三区蜜桃| 欧美激情a在线| 精品久久ai电影| 日韩欧美国产免费| 久久尤物电影视频在线观看| 国产性生活视频| 色七七影院综合| 久久免费福利| 青青草成人免费在线视频| 99精品视频免费在线观看| 在线免费观看国产精品| 中文字幕日韩精品在线观看| 日韩福利影视| 欧美国产视频一区| 91首页免费视频| 国模私拍一区二区| 欧美成人中文字幕| 红杏成人性视频免费看| 国模无码视频一区二区三区| 国产亚洲精品aa| 99热这里只有精品9| 性欧美暴力猛交69hd| 自拍亚洲一区| 国产精品久久久久久9999| 亚洲高清不卡在线观看| 邻家有女韩剧在线观看国语| 国产视频福利一区| 精品成人一区| 亚洲精品视频网址| 日韩欧美的一区二区| 三级在线看中文字幕完整版| 亚洲精品乱码视频| 国产成人精品午夜视频免费| 中文字幕第15页| 久久这里有精品视频| 亚洲精品推荐| 中文字幕亚洲影院| 欧美日韩一区二区精品| 日韩子在线观看| 国产综合 伊人色| 久久精品理论片| 日本少妇xxxx动漫| www.欧美三级电影.com| 国产亚洲成av人片在线观黄桃| 亚洲色图久久久| 亚洲一区二区综合| 国产精品一级伦理| 国产亚洲情侣一区二区无| 另类欧美日韩国产在线| 日韩少妇裸体做爰视频| 久久伊人91精品综合网站| 香蕉视频一区| 亚洲av熟女高潮一区二区|