본문 바로가기
Front-end/Vue3

29. 컴포지션 API 활용(lifecycle, refs, props, context)

by devraphy 2021. 5. 28.

1. 반드시 읽어야 하는 공식 문서 

- 지금까지 배운 내용을 컴포지션 API 형태로 작성하기 위해서 반드시 읽는 것을 권장합니다. 

- 전혀 어렵지 않으니 한번쯤 꼭 훑어보고 아래의 전환 예제를 따라 해보기를 권장합니다. 

 

컴포지션 API의 Setup 공식문서

 

컴포지션 API의 라이프사이클 훅 공식문서

 

컴포지션 API의 provide와 inject 공식문서

 

컴포지션 API의 refs 공식문서


2. 컴포지션 API로 코드 전환 예제

 

[기존의 작성 방식]

<template>
  <h1 @click="increase">
    {{ count }} / {{ doubleCount }}
  </h1>
  <h1 @click="changeMessage">
    {{ message }} / {{ reversedMessage }}
  </h1>
</template>
<script>
export default {
  data() {
    return {
      count: 0,
      message: 'Hello world!'
    }
  },
  computed: {
    doubleCount () {
      return this.count * 2
    },

    reversedMessage() {
      return this.message.split('').reversed().join('')
    }
  },
  watch: {
    message(newValue) {
      console.log(newValue)
    }
  },
  created() {
    console.log('created = ', this.message)
  },
  mounted() {
    console.log('mounted = ', this.message)
  },
  methods: {
    increase () {
      this.count += 1
    },

    changeMessage() {
      this.message = 'How are you?!'
    }
  }
}
</script>

 

 

[컴포지션 API 작성방식]

<template>
  <h1 @click="increase">
    {{ count }} / {{ doubleCount }}
  </h1>
  <h1 @click="changeMessage">
    {{ message }} / {{ reversedMessage }}
  </h1>
</template>
<script>
import {ref, computed, watch, onMounted} from 'vue'
export default {
  setup() { 
    // setup() 메소드의 실행 시점은 created와 동일하다. 
    // 그러므로 created 라이프 사이클은 따로 존재하지 않는다.
    console.log('setup = ', message.value)

    // count 관련
    let count = ref(0)
    const doubleCount = computed(() => {
      return count.value * 2
    })
    function increase() {
      count.value += 1
    }

    // message 관련 
    let message = ref('Hello world?')
    const reversedMessage = computed(() => {
      return message.value.split('').reverse().join('')
    })
    watch(message, (newValue) => {
      console.log(newValue)
    })
    function changeMessage() {
      message.value = 'How are you?'
    }

    onMounted(() => {
      console.log('onMounted = ', count.value)
    })

    return {
      count,
      increase,
      doubleCount,
      message,
      reversedMessage,
      changeMessage
    }

  }
}
</script>

 

* 오해하지 말자!

- 기존의 작성방식에 비해 컴포지션 API 방식이 무조건 좋은 것이 아니다. 

- 코드의 복잡도에 따라 가독성 및 이해도의 측면에서 코드를 최적화 할 수 있다는 점이 장점이다. 

- 무엇이든 과유불급이다. 필요에 따라서 사용하도록 하자. 

 


3. props & context

a) 기본코드

[App.vue]

<template>
  <MyBtn
    class="redBtn"
    style="color:red;"
    color="#ff0000"
    @hello="log">
    Apple
  </mybtn>
</template>

<script>
import MyBtn from '~/components/MyBtn'
export default {
  components: {
    MyBtn
  },
  methods: {
    log() {
      console.log('Hello world!')
    }
  }
}
</script>

 

 

[MyBtn.vue]

<template>
  <div
    v-bind="$attrs" 
    class="btn"
    @click="hello">
    <slot></slot>
  </div>
</template>

<script>
export default {
  inheritAttrs: false,
  props: {
    color: {
      type: String,
      default: 'gray'
    }
  },
  emits: ['hello'],
  mounted() {
    console.log(this.color)
    console.log(this.$attrs)
  },
  methods: {
    hello() {
      this.$emit('hello')
    }
  }
}
</script>

 

 

b) 코드 전환

 

[MyBtn.vue]

<template>
  <div
    v-bind="$attrs" 
    class="btn"
    @click="hello">
    <slot></slot>
  </div>
</template>

<script>
import {onMounted} from 'vue'
export default {
  inheritAttrs: false,
  props: {
    color: {
      type: String,
      default: 'gray'
    }
  },
  emits: ['hello'],
  setup(props, context) {
    function hello(context) {
      context.emit('hello') 
    }
    onMounted(() => {
      console.log('props = ', props)
      console.log('context = ',context)

      console.log(props.color)// this.color로 접근이 불가하여 props를 통해 접근
      console.log(context.attrs)// this.$attrs로 접근이 불가하여 context를 통해 접근

    })

    return {
      hello
    }
  }
}
</script>

 

- 컴포지션 API에서는 this로 객체 데이터에 접근이 불가능하다. 

- 그러므로 Props와 Context를 이용하여 접근하는데, 콘솔에서 출력되는 부분을 확인하면 다음과 같다. 

 

[Props로 접근할 수 있는 데이터]

클릭하면 확대됩니다.

 

[Context로 접근할 수 있는 데이터]

클릭하면 확대됩니다.

 

'Front-end > Vue3' 카테고리의 다른 글

31. Vue - 부트스트랩(Bootstrap)  (0) 2021.06.01
30. Vue - 라우터(Router, Routing)  (0) 2021.05.31
28. Vue - 컴포지션 API 작성방법  (0) 2021.05.28
27. Vue - 컴포지션 API란?  (2) 2021.05.28
26. Vue - 컴포넌트 Refs  (0) 2021.05.28

댓글