>웹 프론트엔드 >JS 튜토리얼 >Vue에서 이벤트버스가 여러 번 실행되는 문제를 해결하는 방법

Vue에서 이벤트버스가 여러 번 실행되는 문제를 해결하는 방법

小云云
小云云원래의
2018-05-12 09:39:362537검색

두 페이지 구성 요소 간의 데이터 전송을 실현하기 위한 초기 요구 사항은 다음과 같습니다. 페이지 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가지가 됩니다.

질문:

  1. 질문 1: 페이지 B의 on 이벤트가 처음 발생했을 때 왜 발생하지 않는지

  2. 질문 2: 순차적으로 다시 발생하면 왜 나타나는지, 이전 이벤트 배포가 취소되지 않아 각 이벤트에 의해 점점 더 많은 실행이 발생하는 것으로 보입니다.

Solution

문제 1

이것은 vue의 라이프 사이클부터 시작해야 합니다. 페이지 구성 요소 A에서 페이지 구성 요소 B로 이동할 때 먼저 테스트했습니다. 구성 요소의 수명 주기는 무엇입니까? ? Vue의 라이프 사이클의 각 기간에 대해 자세히 설명하지 않겠습니다. 다음은 Vue의 라이프 사이클에 대한 그림입니다.


페이지 점프 프로세스 중에 이 두 구성 요소의 수명 주기 실행을 확인하기 위해 자체 실험을 수행했습니다.

// 我分别在页面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를 실행하고 소멸됩니다.

그래서 beforeDestory의 A 페이지 컴포넌트에 내보내기 이벤트를 작성할 수 있습니다. 이때 B 페이지 컴포넌트가 생성되었기 때문에, 즉 우리가 작성한 $on 이벤트가 발생했기 때문입니다

그러므로 beforeDestory 중에 $emit 이벤트를 사용해도 괜찮습니다.

// 修改一下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
  })
 },

다음. 수정 후 효과를 살펴보세요


목록을 처음 클릭했을 때, 즉 최초로 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.