4) vue 공식 문서 보면서 메모 3

문서를 순서대로 보는 게 아니라서 꼭지마다 문서 링크를 달았다.

$emit + 커스텀 이벤트

자식 컴포넌트에서 부모 컴포넌트 데이터 수정은 안된다. (데이터가 반응성으로 가지지 않아서 화면 갱신이 안됨)

아래 예시에서 update:msg 라는 커스텀 이벤트를 만들었고 왔다갔다 하면서 데이터 갱신을 시킨다. 요는 데이터 갱신하는 부분의 코드가 부모 컴포넌트에 있어야 한다.

<div id="app">
  <comp-a :msg="message" @update:msg="updateMsg"></comp-a>
  
  <h1></h1>
</div>

<script>
  // 컴포넌트 지역 등록
  const CompA = {
    template: '<button @click="addExclamation">Click!</button>',
    props: {
      msg: String
    },
    methods: {
      addExclamation() {
        // 자식 컴포에서 부모 컴포 데이터 바로 수정하면 반응성을 가지지 않음 
        // this.msg += '!'
        this.$emit('update:msg', this.msg + '!')
      }
    }
  }
  new Vue({
    el: '#app',
    components: {
      CompA
    },
    data() {
      return {
        message: 'Hello Vue'
      }
    },
    methods: {
      updateMsg(newMsg) { // 자식 컴포에 있는 this.msg + '!' 부분이 들어옴. 데이터 갱신은 부모 컴포넌트가 해야한다는 것. 
        this.message = newMsg
      }
    }
  })
</script>

.sync, v-on을 이용한 사용자 지정 이벤트

https://kr.vuejs.org/v2/guide/components.html#sync-수식어

.sync를 이용해 간단하게 표현할 수 있다.

<div id="app">
  <comp-a :msg.sync="message"></comp-a>
  <h1></h1>
</div>

<script>
  // 컴포넌트 지역 등록
  const CompA = {
    template: '<button @click="addExclamation">Click!</button>',
    props: {
      msg: String
    },
    mounted() {
      // 생성한 커스텀 이벤트를 청취. 이벤트가 발생할 때 콜백 실행
      this.$on('update:msg', newMsg => {
        console.log('$on:', newMsg)
      })
    },
    methods: {
      addExclamation() {
        // .sync를 사용할 때 Event 이름은 update: 로 시작해서 뒤에 prop이름을 붙여야 한다. 
        this.$emit('update:msg', this.msg + '!')
      }
    }
  }
  new Vue({
    el: '#app',
    components: {
      CompA
    },
    data() {
      return {
        message: 'Hello Vue'
      }
    }
  })
</script>

존재하는 속성 교체/병합

https://kr.vuejs.org/v2/guide/components.html#존재하는-속성-교체-병합

대부분 컴포넌트에 제공된 값이 설정된 값을 대체한다. class, style은 값이 합쳐진다. 해당 컴포넌트의 최상의 요소가 하나일 때 가능하다. 최상의 요소와 컴포넌트의 관계에서 일어나는 일이다.

<div id="app">
  <comp-a class="disabled" style="font-weight: normal;" title="Gooooood!"></comp-a>
</div>

<script>
  const CompA = {
    template: '<h1 class="active" style="color: salmon;" title="Hello Vue">Vue!</h1>',
  }
  new Vue({
    el: '#app',
    components: {
      CompA
    }
  })
</script>

결과물

<h1 title="Gooooood!" class="active disabled" style="color: salmon; font-weight: normal;">Vue!</h1>

비 부모-자식간 통신

https://kr.vuejs.org/v2/guide/components.html#비-부모-자식간-통신

데이터를 태워서 보낼 컴포넌트를 만들어서 데이터 이동용으로만 사용한다. 권장되지는 않는 방법이다. 아주 단순한 데이터 이동일 때만 고려해볼 수 있지만 프로젝트 커지면 vuex 도입을 권장.

<div id="app">
  <comps>
    <comp-a></comp-a>
    <comp-b></comp-b>
  </comps>
  <comp-b></comp-b>
</div>

<script>
  // 전역 생성한 컴포넌트를 버스용으로만 쓴다. 
  const bus = new Vue()

  const Comps = {
    template: '<div><h1>Components</h1><slot></slot></div>'
  }

  const CompA = {
    template: '<button @click="getOnBus">CompA</button>',
    methods: {
      getOnBus() {
        bus.$emit('nameOnBus', 'JENNIE')
      }
    }
  }
  const CompB = {
    template: '<h1>Hi~ </h1>',
    data() {
      return {
        user: '...'
      }
    },
    created() {
      bus.$on('nameOnBus', userName => {
        this.user = userName
      })
    }
  }
  new Vue({
    el: '#app',
    components: {
      Comps,
      CompA,
      CompB
    }
  })
</script>

범위를 가지는 슬롯

https://kr.vuejs.org/v2/guide/components.html#범위를-가지는-슬롯

유용한 기능이지만 일반적인 환경에서 쓸 일이 없을 수 있다.

<div id="app">
  <comp-a>
    <template slot-scope="props">
      <div> JENNIE!</div>
    </template>
  </comp-a>
  
  <comp-a>
    <!-- 객체 구조분해 할당 활용 -->
    <template slot-scope="{ myText }">
      <div> JENNIE!</div>
    </template>
  </comp-a>
</div>

<script>
  const CompA = {
    template: 
      `<div>
        <h1>CompA</h1>  
        <slot my-text="Hi~"></slot>
      </div>`
  }

  new Vue({
    el: '#app',
    components: {
      CompA
    }
  })
</script>

동적 컴포넌트

https://kr.vuejs.org/v2/guide/components.html#동적-컴포넌트

화면에 출력을 했다 안했다 하는 것. <component>태그와 is 속성을 사용한다.

예시에서 버튼을 눌러서 바뀔 때 이전 컴포넌트는 파괴된다.(destroyed)

keep-alive엘리먼트로 래핑하면 메모리에 유지된다. (파괴되지 않고 데이터 반응성이 유지된다.)

https://kr.vuejs.org/v2/api/?#keep-alive

api부분 문서에서 보면 keep alive안에 있으면 라이프사이클에서 activatedeactivated 를 사용할 수 있다.

See the Pen vue_keep-alive by kabinny (@kabinny) on CodePen.

Vue CLI

https://cli.vuejs.org/

뷰 프로젝트를 빠르게 생성해주는, 리액트의 create-react-vue같은 것. 뷰가 익숙해지고 잘 쓸 수 있게 되고 난 다음 편의를 위해서는 사용할 수 있다.

Leave a comment