Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Interpretation von Eventbus in Vue

Detaillierte Interpretation von Eventbus in Vue

亚连
亚连Original
2018-06-22 18:07:501638Durchsuche

In diesem Artikel werden hauptsächlich die Fallstricke vorgestellt, die auftreten, wenn Eventbus in Vue mehrmals ausgelöst wird und darauf getreten wird. Der Herausgeber findet es ziemlich gut, daher werde ich es jetzt mit Ihnen teilen und als Referenz verwenden. Folgen wir dem Editor und werfen wir einen Blick darauf.

Um die Datenübertragung zwischen zwei Seitenkomponenten zu realisieren, gehe ich davon aus, dass ich Seite A habe und auf eine Schaltfläche auf Seite A klicke Die Seite springt automatisch zu Seite B. Gleichzeitig hoffe ich, einige Parameter von Seite A auf Seite B zu übertragen. (Ich weiß, dass Sie für kleine Parameter Parameter über Routenparameter oder Abfragen übergeben können oder große Datenmengen mit Vuex verarbeitet werden können. Leider habe ich noch kein sehr großes Projekt durchgeführt, daher habe ich Vuex noch nicht verwendet. Weiter Werde es erfahren.)

Dann dachte ich, ist das nicht nur ein Problem der Datenübertragung zwischen verschiedenen Komponenten? Würde es nicht ausreichen, das Busereignis direkt zur Datenübertragung zu nutzen? Also machte ich glücklich weiter. Was die Verwendung von Eventbus in Vue betrifft, habe ich es bereits in einem Artikel über die Datenübertragung in Vue erwähnt.

Lassen Sie mich Ihnen zuerst meinen ursprünglichen Code zeigen:

Ziel erreichen:

Nach dem Klicken wird das Bus-Emit-Ereignis auf die Seite /moneyRecord umgeleitet.

Der nächste Schritt besteht darin, dieses Ereignis auf der MoneyRecord-Seite zu empfangen und dann die Parameter zu akzeptieren.

// 这是页面A的内部触发bus事件的代码
 editList (index, date, item) {
// 点击进入编辑的页面,需要传递的参数比较多。
  console.log(index, date, item)
  bus.$emit('get', {
  item: item.type,
  date: date
  })
  this.$router.replace({path: '/moneyRecord'})
 }

// moneyRecord页面
created () {
 //这里我将icon的list给保存下来了
 bus.$on('get', this.myhandle)
 },
methods: {
 myhandle (val) {
  console.log(val, '这是从上个页面传递过来的参数')
 }
}

Gerade als ich begeistert war, hatte ich das Gefühl, dass Seite B die Daten wie selbstverständlich akzeptieren würde, solange ich das Get-Ereignis auf Seite A auslöste. Allerdings war das Ergebnis nicht zufriedenstellend, schauen Sie sich die Animation unten an.

Beurteilen Sie die Anzahl der Ereignisauslöser hauptsächlich anhand der Häufigkeit, mit der die Datenzeile „Dies sind die von der vorherigen Seite übertragenen Daten“ ausgegeben wird. ""

Ich weiß nicht, ob Sie es bemerkt haben, aber als ich die Listenseite zum ersten Mal betrat, klickte ich auf ein beliebiges Element unter der Liste und es gab keine Ausgabe auf der Konsole. Aber wenn ich zum zweiten Mal klicke, um das Ereignis auszulösen, werden Testdaten ausgegeben. Klicken Sie erneut hinein und es werden zwei Daten ausgegeben. . . Der Reihe nach erhöht. (Das „Dies sind die von der vorherigen Seite übertragenen Daten“ auf der Konsole sind die Testdaten)

Es gibt also zwei Fragen.

Frage:

  1. Frage 1: Warum wird das Ein-Ereignis auf Seite B nicht ausgelöst, wenn es zum ersten Mal ausgelöst wird

  2. Frage 2: Warum erscheint es, wenn ich es nacheinander erneut auslöse? Jedes Mal stelle ich fest, dass die vorherige Ereignisverteilung nicht widerrufen wurde, was dazu führt, dass immer mehr Ereignisauslöser ausgeführt werden jedesmal.

Lösung

Für Problem 1

Das muss mit dem Lebenszyklus von Vue beginnen, ich werde es zuerst tun Beim Testen geht es darum, von Seitenkomponente A zu Seitenkomponente B zu wechseln. Ich werde nicht näher darauf eingehen, was der Lebenszyklus von Vue in den einzelnen Perioden bewirkt Vue-Lebenszyklus.

Ich habe meine eigenen Experimente durchgeführt, um die Ausführung der Lebenszyklen dieser beiden Komponenten während des Seitensprungprozesses zu überprüfen.

// 我分别在页面A和页面B中去添加以下代码:
beforeCreate () {
 console.group('%c%s', 'color:red', 'beforeCreate 创建前状态===============组件2》')
 },
 created () {
 console.group('%c%s', 'color:red', 'created 创建完毕状态===============组件2》')
 },
 beforeMount () {
 console.group('%c%s', 'color:red', 'beforeMount 挂载前状态===============组件2》')
 },
 mounted () {
 console.group('%c%s', 'color:red', 'mounted 挂载状态===============组件2》')
 },
 beforeUpdate () {
 console.group('%c%s', 'color:red', 'beforeUpdate 更新前状态===============组件2》')
 },
 updated () {
 console.group('%c%s', 'color:red', 'updated 更新状态===============组件2》')
 },
 beforeDestroy () {
 console.group('%c%s', 'color:red', 'beforeDestroy 破前状态===============组件2》')
 },
 destroyed () {
 console.group('%c%s', 'color:red', 'destroyed 破坏状态===============组件2》')
 }
// 另外一个组件的我就不放出来了

Bild des Testergebnisses:

Tatsächlich können wir anhand der Ergebnisse deutlich erkennen, dass wir still sind auf Seite A Zu diesem Zeitpunkt wurde Seite B noch nicht generiert, d. h. das von A überwachte Ereignis, das auf Seite B erstellt wurde, wurde noch nicht ausgelöst. Zu diesem Zeitpunkt, als Sie das Ereignis in A ausgeben, hat B es tatsächlich nicht überwacht.

Schauen Sie noch einmal, die rote Seite ist die B-Seitenkomponente. Was passiert, wenn Sie von Seite A zu Seite B springen? Zuerst wird zuerst die B-Komponente erstellt, dann beforeMount, dann wird die A-Komponente zerstört und dann wird die A-Komponente beforeDestory ausgeführt und destoryed.

So können wir das Emit-Ereignis in die A-Seitenkomponente in beforeDestory schreiben . Da zu diesem Zeitpunkt die B-Seitenkomponente erstellt wurde, wurde das von uns geschriebene $on-Ereignis

ausgelöst. Daher ist es in Ordnung, das $emit-Ereignis während beforeDestory zu verwenden.

// 修改一下A页面中的代码:
// 这是原先的代码
 editList (index, date, item) {
// 点击进入编辑的页面,需要传递的参数比较多。
  console.log(index, date, item)
  this.item = item.type
  this.date = date
  this.$router.replace({path: '/moneyRecord'})
 }
// 重新在data属性内部定义新的变量,来存储要传过去的数据;
然后:
 beforeDestroy () {
 console.log(this.highlight, '这是今年的数据', this, '看看组件销毁之前会发生什么')
 bus.$emit('get', {
  item: this.item,
  date: this.date
  })
 },

Weiter. Schauen Sie sich den Effekt nach der Änderung an

Das sehen Sie, wenn Sie zum ersten Mal auf die Liste klicken, also wenn das Emit-Ereignis zum ersten Mal ausgelöst wird Zeit wird das Steuerelement ausgegeben, daher spielt es eine Rolle, $emit beforeDestoryed auszugeben, und die B-Seitenkomponente überwacht auch das Eintreffen von $on.

Es scheint jedoch, dass selbst das Auslösen von Ereignissen der Reihe nach immer noch zunimmt, das heißt, die Ausgabe der Konsole wird jedes Mal zunehmen. . .

Lösung:

Sehen Sie sich an, was auf Github vorgeschlagen wurde. https://github.com/vuejs/vue/issues/3399

You Dada hat die folgende Lösung vorgeschlagen:

*就是说,这个$on事件是不会自动清楚销毁的,需要我们手动来销毁。(不过我不太清楚这里的external bus 是什么意思,有大神能解答一下的吗,尤大大也提到如果是注册的是external bus 的时候需要清除)****

所以。我在B组件页面中添加Bus.$off来关闭。代码如下:

// 在B组件页面中添加以下语句,在组件beforeDestory的时候销毁。
 beforeDestroy () {
 bus.$off('get', this.myhandle)
 },

来看一下输出的结果

t可以看到,控制台第一次进去的时候就有输出,而且输出的不会逐次增加

*当然,尤大大还说可以写一个mixin?我还不知道是什么?以后在研究一下。

总结: 所以,如果想要用bus 来进行页面组件之间的数据传递,需要注意亮点,组件A$emit事件应在beforeDestory生命周期内。其次,组件B内的$on记得要销毁。

提问时间:你们在实现页面组件之间的数据传递有什么好的方法吗?可以留言分享一下吗?有时候虽然也可以通过从后台获取,但是考虑到数据只有几个需要传的话,就没有必要去请求数据,我知道有的还有用vueX传递。还有呢?

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用EasyUI如何绑定Json数据源

在vue-cli中如何实现组件通信

Vue项目优化需要注意哪些?

在vuejs中使用模块化的方式开发

Das obige ist der detaillierte Inhalt vonDetaillierte Interpretation von Eventbus in Vue. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn