成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Vue2.0父子組件間事件派發(fā)機(jī)制

xietao3 / 3556人閱讀

摘要:從過(guò)來(lái)的都知道,在中,父子組件間事件通信的和被移除了。通過(guò)廣播和事件分發(fā)的機(jī)制,就顯得比較混亂了。在父組件中中然后,在子組件中,主要在任意事件回調(diào)中使用來(lái)觸發(fā)自定義的事件,后面還可以加上參數(shù)傳給父組件。

從vue1.x過(guò)來(lái)的都知道,在vue2.0中,父子組件間事件通信的$dispatch$broadcase被移除了。官方考慮是基于組件樹(shù)結(jié)構(gòu)的事件流方式實(shí)在是讓人難以理解,并且在組件結(jié)構(gòu)擴(kuò)展的過(guò)程中會(huì)變得越來(lái)越脆落。特別是在組件層級(jí)比較深的情況下。通過(guò)廣播和事件分發(fā)的機(jī)制,就顯得比較混亂了。

官方在廢除的同時(shí),也為我們提供了替換方案,包括實(shí)例化一個(gè)空的vue實(shí)例,使用$emit反應(yīng)子組件上的狀態(tài)變化

1.使用$emit觸發(fā)事件

helloWorld.vue作為父組件,dialogConfigVisible變量控制子組件彈框顯示或隱藏。
configBox.vue作為子組件,假設(shè)為封裝的公告彈窗。

在父組件中 helloWorld.vue 中

< template/>

    

script

  data(){
    return {
      dialogConfigVisible:true
    }
  }
   methods: {
     changeConfigVisible(flag) {
         this.dialogConfigVisible = flag;
     }
   }

然后,在子組件 configBox.vue 中,主要在任意事件回調(diào)中,使用 $emit來(lái)觸發(fā)自定義的 listenToConfig事件,后面還可以加上參數(shù)傳給父組件。比如,在子組件彈窗上點(diǎn)擊×關(guān)閉時(shí),通知父組件 helloWorld.vue我要關(guān)閉了,主要方便父組件改變相應(yīng)狀態(tài)變量,并傳入false到自定義的事件中。

script

methods:{
  dialogClose() {
    this.show = false;
    this.$emit("listenToConfig", false)
  }
}

在子組件中,主動(dòng)觸發(fā)listenToConfig事件,并傳入?yún)?shù) false, 告訴父組件 helloWorld.vue對(duì)話框要關(guān)閉了。這里就可以避免父組件中的狀態(tài)未變化,再次刷新頁(yè)面的時(shí)候?qū)υ捒驎?huì)自動(dòng)出現(xiàn)。

2.實(shí)例化一個(gè)空的vue實(shí)例bus

這里實(shí)例化一個(gè)bus 空vue實(shí)例,主要為了統(tǒng)一管理子組件和父組件相互通信,通過(guò)bus 作為媒介,
首先新建一個(gè)bus.js 文件,在里面新建一個(gè)對(duì)象,父組件為table.vue, 子組件為tableColumn.vue

  // bus.js
 import Vue from "vue";
 export var bus = new Vue({
     data:{
       scrollY:false
     },
     methods:{
        updateScrollY(flag){
          this.scrollY = flag;
        }
     }
   })

然后分別引入:

 // table.vue
 

  // tableColumn.vue
  

上面的父子組件中,父組件中利用bus注冊(cè)監(jiān)聽(tīng)事件getData,子組件中一旦有狀態(tài)變化,就觸發(fā)bus上對(duì)應(yīng)的事件。

這種利用空實(shí)例的方式,相當(dāng)于創(chuàng)建了一個(gè)事件中心,所以這種通信同樣適用于非父子組件間的通信,

3.多級(jí)父子組件通信

有時(shí),可能想要實(shí)現(xiàn)通信的兩個(gè)組件不是直接的父子組件,而是祖父和孫子,或者是跨越了更多層級(jí)的父子組件

不可能由子組件一級(jí)一級(jí)的向上傳遞參數(shù),來(lái)達(dá)到通信的目的,雖然現(xiàn)在我們理解的通信都是這樣經(jīng)過(guò)中轉(zhuǎn)的??梢酝ㄟ^(guò)while等循環(huán),不斷向上遍歷,直到找到目標(biāo)父組件,就在對(duì)應(yīng)的組件上觸發(fā)事件。

下面就只element-ui實(shí)現(xiàn)的一個(gè)父子組件通信的mixins,對(duì)于組件同步有很大的作用。在element-ui 的優(yōu)點(diǎn)概述中也特意提到這個(gè)組件通信

function broadcast(componentName, eventName, params) {

  // 向下遍歷每個(gè)子節(jié)點(diǎn),觸發(fā)相應(yīng)的向下廣播的 事件
  this.$children.forEach(child => {
    var name = child.$options.componentName;

    if (name === componentName) {
      child.$emit.apply(child, [eventName].concat(params));
    } else {
      broadcast.apply(child, [componentName, eventName].concat([params]));
    }
  });
}
export default {
  methods: {
     // 向上遍歷父節(jié)點(diǎn),來(lái)獲取指定父節(jié)點(diǎn),通過(guò)$emit 在相應(yīng)的 組件中觸發(fā) eventName  事件
    dispatch(componentName, eventName, params) {
      var parent = this.$parent || this.$root;
      var name = parent.$options.componentName;
      // 上面的componentName 需要在每個(gè)vue 實(shí)例中額外配置自定義屬性 componentName,
      //可以簡(jiǎn)單替換成var name = parent.$options._componentTag;

      while (parent && (!name || name !== componentName)) {
        parent = parent.$parent;

        if (parent) {
          name = parent.$options.componentName;
        }
      }
      if (parent) {
        parent.$emit.apply(parent, [eventName].concat(params));
      }
    },
    broadcast(componentName, eventName, params) {
      broadcast.call(this, componentName, eventName, params);
    }
  }
};

首先定義兩個(gè)嵌套的組件 f1.vue 和 c1.vue,實(shí)例是:

 
   
 

然后,分別定義兩個(gè)父子組件:

c2.vue

 
 f1.vue



這樣,就可以在子組件中點(diǎn)擊按鈕,觸發(fā) listenerToC1事件,在父組件中監(jiān)聽(tīng)到這個(gè)事件,
其實(shí)更$emit觸發(fā)事件類似。不同之處在于,這里可以多級(jí)嵌套,不一定是直接的父子組件都可以觸發(fā)到。

4 .sync 修飾符

在Vue1.x中,利用prop進(jìn)行"雙向綁定",實(shí)現(xiàn)父子組件通信,都會(huì)用到.sync修飾符,可以將子組件中對(duì)應(yīng)的prop值變化同步到父組件中。但是,這樣就破壞了單向數(shù)據(jù)流,在2.0版本中被移除了,在2.3.0版本中又以一種語(yǔ)法糖的形式加了進(jìn)來(lái)。
可以看下文檔上給出的實(shí)例

   

被擴(kuò)展為

  

其實(shí)跟本文中第一種方法基本一致,更加簡(jiǎn)化了。

同樣helloWorld.vue作為父組件, configBox.vue作為子組件,

      

然后在子組件中,顯式的觸發(fā)更新事件:

methods:{
  dialogClose() {
    this.show = false;
    this.$emit("update:visible", false)
  }
}

這樣visible 的變化就能同步到父組件中了。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/90697.html

相關(guān)文章

  • vue2.0組件事件派發(fā)與接收

    摘要:官方給出的最簡(jiǎn)單的升級(jí)建議是使用集中的事件處理器而且也明確說(shuō)明了一個(gè)空的實(shí)例就可以做到因?yàn)閷?shí)例實(shí)現(xiàn)了一個(gè)事件分發(fā)接口在中在初始化之前,給添加一個(gè)名字為的空對(duì)象某一個(gè)組件內(nèi)調(diào)用事件觸發(fā)另一個(gè)組件內(nèi)調(diào)用事件接收在組件銷毀時(shí)接除事件綁定使用方法 在vue的開(kāi)發(fā)中,經(jīng)常會(huì)在兩個(gè)組件間進(jìn)行事件的通信 在vue1.0中我們使用$dispatch 和 $broadcast child.vue: th...

    luckyw 評(píng)論0 收藏0
  • vue2.0組件事件派發(fā)與接收

    摘要:官方給出的最簡(jiǎn)單的升級(jí)建議是使用集中的事件處理器而且也明確說(shuō)明了一個(gè)空的實(shí)例就可以做到因?yàn)閷?shí)例實(shí)現(xiàn)了一個(gè)事件分發(fā)接口在中在初始化之前,給添加一個(gè)名字為的空對(duì)象某一個(gè)組件內(nèi)調(diào)用事件觸發(fā)另一個(gè)組件內(nèi)調(diào)用事件接收在組件銷毀時(shí)接除事件綁定使用方法 在vue的開(kāi)發(fā)中,經(jīng)常會(huì)在兩個(gè)組件間進(jìn)行事件的通信 在vue1.0中我們使用$dispatch 和 $broadcast child.vue: th...

    JayChen 評(píng)論0 收藏0
  • vue2.0組件事件派發(fā)與接收

    摘要:官方給出的最簡(jiǎn)單的升級(jí)建議是使用集中的事件處理器而且也明確說(shuō)明了一個(gè)空的實(shí)例就可以做到因?yàn)閷?shí)例實(shí)現(xiàn)了一個(gè)事件分發(fā)接口在中在初始化之前,給添加一個(gè)名字為的空對(duì)象某一個(gè)組件內(nèi)調(diào)用事件觸發(fā)另一個(gè)組件內(nèi)調(diào)用事件接收在組件銷毀時(shí)接除事件綁定使用方法 在vue的開(kāi)發(fā)中,經(jīng)常會(huì)在兩個(gè)組件間進(jìn)行事件的通信 在vue1.0中我們使用$dispatch 和 $broadcast child.vue: th...

    My_Oh_My 評(píng)論0 收藏0
  • 聊聊Vue.js組件通信的幾種姿勢(shì)

    摘要:子組件向父組件通信方法一使用事件父組件向子組件傳遞事件方法,子組件通過(guò)觸發(fā)事件,回調(diào)給父組件。非父子組件兄弟組件之間的數(shù)據(jù)傳遞非父子組件通信,官方推薦使用一個(gè)實(shí)例作為中央事件總線。 寫(xiě)在前面 因?yàn)閷?duì)Vue.js很感興趣,而且平時(shí)工作的技術(shù)棧也是Vue.js,這幾個(gè)月花了些時(shí)間研究學(xué)習(xí)了一下Vue.js源碼,并做了總結(jié)與輸出。 文章的原地址:https://github.com/answ...

    Profeel 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<