Composition API

jude·2022년 2월 16일
0

vue

목록 보기
11/14
post-thumbnail

Composition API 사용 이유

composition API는 분산되어 있는 로직을, 관련 있는 로직들끼리 그룹핑하기 위해 만들어졌다.

기존 문법은 아래와 같이 여러 로직들이 섞인채로 작성되도록 설계되어 있다.

<!-- 기존 문법 -->
<template>
  <h2 @click="increase">
    {{ count }}
  </h2>
  <h2 @click="changeMessage">
    {{ message }}
  </h2>
</template>

<script>

export default {
  data() {
    return {
      count: 0, // count 관련 로직
      message: 'Hello jude' // message 관련 로직
    }
  },
  methods: {
    increase() { // count 관련 로직
      this.count += 1
    },
    changeMessage() { // message 관련 로직
      this.message = 'text change'
    }
  }
}
</script>

하지만 composition api 문법을 사용하면 아래와 같이 관련 있는 로직별로 그룹핑하는 것이 가능해진다.

<template>
  <h2 @click="increase">
    {{ count }}
  </h2>
  <h2 @click="changeMessage">
    {{ message }}
  </h2>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0) // count 관련 로직
    const increase = () => count.value += 1 // count 관련 로직

    const message = ref('Hello jude') // message 관련 로직
    const changeMessage = () => message.value = 'text change' // message 관련 로직

    return {
      count, // count 관련 로직
      increase, // count 관련 로직
      
      message, // message 관련 로직
      changeMessage // message 관련 로직
    }
  }
}
</script>

setup() 함수 안의 로직에 사용된 변수들은 객체로 만들어서 return 시키면 template에서 사용할 수 있다.

반응성 주입하기

setup() 함수 안에 사용되는 원시값(Number, String, Boolean 등..)들은 기본적으로 반응성을 가지고 있지 않다.

때문에 반응성을 주입해주기 위해 vue 패키지로부터 ref 메서드를 가져와서 원시값들을 아래와같이 래핑해서 사용한다.

const count = ref(0)

ref 메서드는 원시값을 value 키로 감싼 객체를 반환 시킨다.
때문에 원시값들을 사용할 땐 count.value와 같이 체이닝 하여 사용해야 한다.

console.log( count ) // { value: 0 }
console.log( count.value ) // 0

반응성을 주입한 변수를 setup() 함수 안에서 사용할 땐 value 프로퍼티에 접근하여 사용해야하지만, return키워드로 반환할 때는 자동으로 래핑 해제되기 때문에 value 프로퍼티 없이 그대로 반환하여 사용할 수 있다.

<template>
  <div>{{ count }}</div><!-- 0 -->
</template>

<script>
import { ref } from 'vue'

export default {  
  setup() {
    const count = ref(0)
    console.log( count.value ) // 0

    return {
      count
    }
  }
}
</script>

computed 사용

  • computed()는 ref처럼 vue 패키지에서 import하여 사용한다.
  • computed() 함수 호출을 할 때 인자에 콜백함수를 넣어 계산된 로직을 작성한다.
<template>
  <div>{{ count }}</div><!-- 1 -->
  <div>{{ doubleCount }}</div><!-- 2 -->
</template>

<script>
import { ref, computed } from 'vue'

export default {  
  setup() {
    const count = ref(1)
    const doubleCount = computed(() => count.value * 2)

    return {
      count,
      doubleCount
    }
  }
}
</script>

watch 사용

  • watch() 역시 vue 패키지에서 import하여 사용한다.
  • watch() 함수는 별도로 return 시킬 필요가 없다.
  • 첫번째 인자는 바라보고 있을 데이터명을 작성한다.
  • 두번째 인자콜백함수이며 데이터가 변경됐을 때 호출된다.
    • 콜백함수가 호출될 때 첫번째 매개변수변경된 값이 들어온다.
<template>
  <div>{{ count }}</div><!-- 1 -->
  <div>{{ doubleCount }}</div><!-- 2 -->
  <button @click="increase">증가 버튼</button>
</template>

<script>
import { ref, computed, watch } from 'vue'

export default {  
  setup() {
    const count = ref(1)
    const doubleCount = computed(() => count.value * 2)
    function increase() {
      count.value += 1
    }
    watch(doubleCount, newVal => {
      console.log( newVal )
    })
  
    return {
      count,
      doubleCount,
      increase
    }
  }
}
</script>

props, emit, 속성 상속

  • Child 컴포넌트로 class와 style 속성을 내려보내고 있다.
  • Child 컴포넌트로 color라는 props를 내려보내고 있다.
  • Child 컴포넌트로부터 childEvt 이벤트가 발생하면, log 함수를 호출한다.
<!-- App.vue -->
<template>
  <Child
    class="jude"
    style="color:red"
    color="#ff0000"
    @childEvt="log">
    Apple
  </Child>
</template>

<script>
import Child from './components/Child'

export default {
  components: {
    Child
  },
  methods: {
    log() {
      console.log( 'Hello jude!' )
    }
  }
}
</script>
  • App.vue에서 받은 속성들을 v-bind="$attrs"로 모두 상속받고 있다.
  • div를 클릭하면 hello 함수가 호출된다.
  • 클릭으로 hello 함수가 호출되면, emit을 통해 App.vue(부모 컴포넌트)에 childEvt 이벤트를 호출 시킨다.
  • composition api 문법에선 created 라이프 사이클이 없다. setup() 함수에 작성하면 된다.
  • composition api라이프사이클 훅은 vue 패키지로부터 import해서 사용하며, 이름이 기본 문법과 다르게 접두사로 on이 들어가고 카멜케이스로 작성한다.(ex. onMounted)
  • onMounted() 라이프사이클 훅은 함수처럼 호출하고, 인자로 익명의 콜백함수를 선언하여 코드를 작성한다.
  • setup() 함수의 첫번째 매개변수로 props가 들어오고, 두번째 매개변수로 context 객체가 들어온다.
    • props
      • 주의사항 : props에 es6의 구조분해할당을 사용하면 반응성이 제거된다.
    • context
      • context는 attrs, slots, emit객체를 가져와 활용할 수 있다.
<!-- Child.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: ['childEvt'],
  setup(props, context) {
    function hello() {
      context.emit('childEvt')
    }
    onMounted(() => {
      console.log(props.color);
      console.log(context.attrs);
    })
    

    return {
      hello
    }
  }
}
</script>
<!-- 렌더된 코드 -->
<div class="jude btn" style="color: red;"> Apple </div>
profile
UI 화면 만드는걸 좋아하는 UI개발자입니다. 프론트엔드 개발 공부 중입니다. 공부한 부분을 블로그로 간략히 정리하는 편입니다.

0개의 댓글