この記事では、Vue でイベントバスが複数回トリガーされることによる落とし穴を中心に紹介します。編集者が非常に優れていると考えたので、参考として共有します。エディターをフォローして見てみましょう
2 つのページ コンポーネント間のデータ転送を実現するために、ページ A があるとします。ページ A のボタンをクリックすると、ページは自動的にページにジャンプします。 B で、ページ A のいくつかのパラメータをページ B に運びたいと考えています。 (小さなパラメーターの場合は、ルート パラメーターまたはクエリを通じてパラメーターを渡すことができ、大きなデータは vuex で処理できることはわかっています。残念ながら、私はまだそれほど大規模なプロジェクトを行っていないため、まだ vuex を使用していません。それについては勉強します)
そこで、これは異なるコンポーネント間のデータ転送の問題ではないかと思いました。バスイベントを直接使用してデータを転送すれば十分ではないでしょうか?ということで、楽しく進んでいきました。 Vue でのイベントバスの使用については、以前 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: ページ B の on イベントが初めてトリガーされたときにトリガーされないのはなぜですか
質問 2: 順番に再度トリガーされたときに表示されるのはなぜですか、毎回、以前のイベント配布が取り消されていないように見えるため、各イベントによってトリガーされる実行がますます増えていることがわかります。
解決策
問題1の場合
これはvueのライフサイクルから始める必要があります。つまり、ページコンポーネントAからページコンポーネントBにジャンプするとき、2つのコンポーネントは何ですか? Vue のライフ サイクルについては、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 イベントがトリガーされたときに、コントロールが出力されることがわかります。 beforeDestoryed の $emit には効果があります。これは機能し、B ページ コンポーネントも到着時の $ を監視します。
ただし、イベントのトリガーでも引き続き順次増加、つまりコンソールの出力が毎回増加するようです。 。 。
解決策:
github で提案されたものを見てください。 https://github.com/vuejs/vue/issues/3399
次の解決策を提案しました:
*就是说,这个$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传递。还有呢?
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
以上がvueのeventbusの詳細な解釈の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。