개발/Nuxt.js

nuxt.js - event와 eventBus 예제 및 사용법

반응형

서론

이번 프로젝트를 하면서 페이지가 너무 길어서 부모/자식 컴포넌트로 적용했다가 자식 컴포넌트에서 또 자식 컴포넌트를 만들고..그렇게 점점 분리하다보니 데이터 이동이 점점 복잡해지고 힘들어서 정리를 하기로 하면서 event와 eventBus에 대해 작성하게 되었다.

 

부모 자식 간의 데이터 양반향 이동(바인딩) - props & emit

vue.js를 하다보면 가장 기본적으로 하게되는 방식입니다.

  • 부모 → 자식 데이터 이동

위의 방법은 간단하게 부모 데이터를 자식에게 전달해주고 자식 컴포넌트에서 props로 받으면 됩니다.

 

parent.vue - isAlive 라는 data를 선언하고 child.vue에 데이터를 넘긴다.

<template>
  <div>
    <h1>parent</h1>
    isAlive : {{ isAlive }}
    <child :is-alive="isAlive" />
  </div>
</template>

<script>
import child from '~/components/child'

export default {
  components: { child },
  data () {
    return {
      isAlive: true
    }
  },
}
</script>

child.vue - 부모 컴포넌트에서 넘긴 데이터를 props로 받는다.

<template>
  <div>
    <h1>child</h1>
    isAlive: {{ isAlive }}
  </div>
</template>

<script>
export default {
  props: {
    isAlive: {
      type: Boolean,
      required: false
    }
  }
}
</script>

 

  • 자식 → 부모 데이터 이동

이건 부모 → 자식 데이터와 다르게 그냥 데이터를 넘길수 없다. 부모의 method를 이용하여 데이터를 받아야한다.

 

child.vue - $emit를 이용하여 childDeadEvent과 연결되어있는 메소드를 호출한다.

* 단 props 데이터를 직접 수정해서 전달할수 없다. 이부분은 추후 다시 정리하도록 하겠다.

<template>
  <div class="child">
    <h1>child</h1>
    isAlive: {{ isAlive }}
    <br>
    <br><br><input type="button" value="parent onDeadEvent 함수 호출" @click="childDeadEvent">
  </div>
</template>

<script>
export default {
  props: {
    isAlive: {
      type: Boolean,
      required: false
    }
  },
  methods: {
    childDeadEvent () {
      this.$emit('childDeadEvent', !this.isAlive)
    }
  }
}
</script>

parent.vue - 자식 컴포넌트에서 @childDeadEvent라는 이름으로 event를 발생시키면 onDeadEvent의 메소드를 실행한다.

<template>
  <div id="parent">
    <h1>parent</h1>
    isAlive : {{ isAlive }}
    <child :is-alive="isAlive" @childDeadEvent="onDeadEvent" />
  </div>
</template>

<script>
import child from '~/components/child'

export default {
  components: { child },
  data () {
    return {
      isAlive: true
    }
  },
  methods: {
    onDeadEvent (isAlive) {
      this.isAlive = isAlive
    }
  }
}
</script>

 

여기까지는 간단한 vue.js의 양방향 데이터 바인딩 방식이다. 그런데 복잡한 화면을 하다보면 자식의 자식 컴포넌트가 부모에게 데이터를 전달할 경우도 있고 서로 독립적인 자식 컴포넌트에서 데이터를 전달할 경우가 생긴다. 자식의 자식 컴포넌트에서 부모에게 넘기는건 자식의 자식 컴포넌트에서 $emit 를 사용하여 자식 컴포넌트에게 전달하고 자식 컴포넌트에서 또 $emit를 사용하여 부모 컴포넌트에게 전달하면 된다. 하지만....자식의자식의자식 컴포넌트에서 데이터를 전달한다면?????? 불필요한 소스를 줄이기 위한 방식이 바로 eventBus이다.

 

독립된 컴포넌트 데이터 단방향 이동(바인딩) - EventBus

이건 단방향으로 작성한 이유는 단방향이지만 A → B 이동과 B → A 이동 그냥 반대로 적용하면 되므로 단방향으로 작성하겠다.

 

child.vue와 child2.vue는 독립된 컴포넌트다.

 

child.vue - created에 $nuxt.$on 을 이용하여 전역에서 호출할수 있는 메소드를 선언한다.

<template>
  <div class="child">
    <h1>child</h1>
    childDate: {{ childDate }}
  </div>
</template>

<script>
export default {
  data () {
    return {
      childDate: 'child data'
    }
  },
  created () {
    this.$nuxt.$on('onChildDeadEventBus', (child2Data) => {
      this.childDate = child2Data
    })
  }
}
</script>

child2.vue - $nuxt.$emit 를 이용하여 전역 메소드를 호출한다.

<template>
  <div class="child2">
    <h1>child2</h1>
    <br>child2Data: {{ child2Data }}
  </div>
</template>

<script>

export default {
  data () {
    return {
      child2Data: 'child2 데이터 가져가라'
    }
  },
  methods: {
    child2DeadEventBus () {
      this.$nuxt.$emit('onChildDeadEventBus', this.child2Data)
    }
  }
}
</script>

 

간단하게 추후 다시 볼수 있게 정리를 하였다. vue.js를 사용하면서 편한 부분이 많지만 부모 / 자식 컴포넌트 구조에서 복잡한 화면일때 데이터 이동이 꽤 힘들었다.(아직 vue.js를 이해를 못해서 그런건지도..??) 이렇게 조금씩 적어가며 나에게 그리고 남에게도 도움이 되었으면 싶다.

반응형