>  기사  >  웹 프론트엔드  >  Vue의 이벤트버스에 대한 자세한 해석

Vue의 이벤트버스에 대한 자세한 해석

亚连
亚连원래의
2018-06-22 18:07:501657검색

이 글에서는 주로 여러 번 촉발된 Vue의 이벤트버스와 밟았던 함정을 소개합니다. 편집자는 그것이 꽤 좋다고 생각하며, 이제 여러분과 공유하고 참고할 것입니다. 편집기를 따라 살펴보겠습니다

두 페이지 구성 요소 간의 데이터 전송을 실현하기 위해 페이지 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가지가 됩니다.

질문:

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

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

Solution

문제 1

이것은 vue의 수명주기부터 시작해야 합니다. 즉, 페이지 구성 요소 A에서 페이지 구성 요소 B로 점프할 때 두 구성 요소는 무엇입니까? Vue의 라이프사이클? 각 기간에서 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 이벤트가 발생했을 때 컨트롤이 출력되는 것을 볼 수 있으니, 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传递。还有呢?

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

相关文章:

使用EasyUI如何绑定Json数据源

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

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

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

위 내용은 Vue의 이벤트버스에 대한 자세한 해석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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