ホームページ > ウェブフロントエンド > jsチュートリアル > Vue でイベントバスが複数回トリガーされる問題を解決する方法

Vue でイベントバスが複数回トリガーされる問題を解決する方法

小云云
リリース: 2018-05-12 09:39:36
オリジナル
2506 人が閲覧しました

2 つのページ コンポーネント間のデータ転送を実現するには、ページ A があるとします。ページ A のボタンをクリックすると、ページは自動的にページ B にジャンプします。同時に、次のことが必要です。ページ A のいくつかのパラメータをページ B に運びます。 (小さいパラメータの場合はルーティングパラメータやクエリでパラメータを渡すか、大きなデータはvuexで処理することができます。) この記事では主にVueの複数回トリガーされるイベントバスと、編集者が踏んだ落とし穴について紹介します。とても良いものですので、皆さんとシェアしてください。皆さんのお役に立てれば幸いです。

目標を達成します:

クリックすると、バス発行イベントが /moneyRecord ページにジャンプします。

次のステップは、MoneyRecord ページに移動してこのイベントを受信し、パラメーターを受け入れることです。

// 这是页面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, '这是从上个页面传递过来的参数')
 }
}
ログイン後にコピー

と有頂天になったところ、ページAでgetイベントをトリガーすれば、ページBは当然のようにデータを受け入れてくれるような気がしました。しかし、結果は満足のいくものではありませんでした。以下のアニメーションをご覧ください。

イベントトリガーの回数は主に「前のページから送信されたデータです」というデータ行が出力された回数を見て判断します。 ""


お気づきかどうかわかりませんが、私が最初にリスト ページに入ったときに、リストの下にある項目をクリックしても、コンソールに出力がありませんでした。ただし、クリックして 2 回目にイベントをトリガーすると、テスト データが出力されます。もう一度クリックすると 2 つのデータが出力されます。 。 。順次増やしていきます。 (コンソール上の「前のページから送信されたデータです」がテストデータです)

そこで質問が2つあります。

質問:

  1. 質問 1: ページ B の on イベントが初めてトリガーされたときにトリガーされないのはなぜですか

  2. 質問 2: 順番に再度トリガーされたときに表示されるのはなぜですか、毎回、以前のイベント配布が取り消されていないように見えるため、各イベントによってトリガーされる実行がますます増えていることがわかります。

解決策

問題1については、vueのライフサイクルから始める必要があります。最初に、ページコンポーネントAからページコンポーネントBにジャンプするときに、2つのコンポーネントのライフサイクルをテストしました。 ? Vue のライフ サイクルの各期間が何を行うかについては詳しく説明しません。Vue のライフ サイクルの図を次に示します。

私は、ページジャンププロセス中のこれら 2 つのコンポーネントのライフサイクルの実行を検証するために独自の実験を行いました。

// 我分别在页面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》')
 }
// 另外一个组件的我就不放出来了
ログイン後にコピー

テスト結果の画像:


実際、この結果から、まだページ A にいるときには、ページ B がまだ生成されていないことがはっきりとわかります。ページ B。A からの監視対象イベントはまだトリガーされていません。この時、Aでイベントを発行すると、実はBはそれを監視していませんでした。

もう一度見てください。赤い部分は B ページのコンポーネントです。ページ A からページ B にジャンプするとどうなりますか?まず、Bコンポーネントが先に作成され、次にbeforeMountが作成され、次にAコンポーネントが破棄され、その後AコンポーネントがbeforeDestoryを実行してdestoryedされます

ということで、beforeDestoryでAページコンポーネントのemitイベントを記述することができます。この時点でBページコンポーネントが作成されている、つまり先ほど書いた$onイベントがトリガーされているので

そのため、beforeDestory中に$emitイベントを使用してもOKです。

えー

次。変更後の効果を見てください

リストが初めてクリックされたとき、つまり、初めて Emit イベントがトリガーされたときに、コントロールが出力されることがわかります。 $emit beforeDestoryed は機能します。B ページ コンポーネントも $on を監視します。

ただし、イベントのトリガーでも引き続き順次増加、つまりコンソールの出力が毎回増加するようです。 。 。

解決策:

github で提案されたものを見てください。 https://github.com/vuejs/vue/issues/3399

あなたは次の解決策を提案しました:

*つまり、この $on イベントは自動的かつ明確に破棄されません。手動で破壊する必要があります。 (しかし、ここでの外部バスが何を意味するのかわかりません。誰か説明できますか? 外部バスを登録する場合は、それをクリアする必要があるとも言いました) ****

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

// 在B组件页面中添加以下语句,在组件beforeDestory的时候销毁。
 beforeDestroy () {
 bus.$off('get', this.myhandle)
 },
ログイン後にコピー

来看一下输出的结果


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

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

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

相关推荐:

guava eventbus实例代码详解

Java-类库-Guava-EventBus

vue微信公众号开发踩坑记录

以上がVue でイベントバスが複数回トリガーされる問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート