Vue.js Composition API ref, props, context(slot, emit), Provide, Injection

강정우·2023년 5월 5일
0

vue.js

목록 보기
50/72
post-thumbnail

<template> ref

  • 작업을 하다보면 optionsAPI에서 compositionAPI로 변환작업을 하다보면 문제가 발생하는 경우가 있을 것이다.
<input type="text" ref="lastNameInput">
<button @click="setLastName"></button>
<script setup>
const lastName = ref('');
const setLastName = (event) => {
  lastName.value = event.target.value;
  lastName.value = this.$refs.lastNameInput.value
}
</script>
  • 라고 가정할 때 위 코드는 작동하지 않는다. 왜? setup 메서드에는 객체를 반환하기에 여기서 자체적으로 참조할 만한 this값이 존재하지 않기 때문이다.
    그래서 this로 접근할 수 없다. 그렇다면 어떻게 접근해야할까?

사용법

<input type="text" ref="lastNameInput">
<button @click="setLastName"></button>
<script setup>
const lastName = ref('');
const lastNameInput = ref(null);
const setLastName = () => {
  lastName = lastNameInput.value.value
}
</script>
  • 여기서 .value가 2번 들어가서 이상하게 보이겠지만 첫번째 .valueconst lastNameInput = ref(null); 에 접근하기위한 drilling이고
    두번째 .value<input type="text" ref="lastNameInput">에 접근하기위한 drilling이다.

props

<user-data :user-name="user.name" :age="user.age"></user-data>

자식 컴포넌트

<template>
  <h2>{{ uName }}</h2>
</template>
<script>
import {computed} from "vue";

export default {
  props: ['userName', 'age'],
  setup(props) {
    const uName = computed(()=>{
      return props.userName + props.age
    })

    return {uName}
  },
}
</script>
  • setup 메서드에는 2가지 인수가 있는데 첫번째가 바로 props이다. 사실 이름은 마음대로 지어도 된다. "properties" 이런식으로 하지만 편의상, 그리고 react에서도 사용했듯 props으로 짓는것이 좋아보인다.

  • props는 부모 컴포넌트에 있는 프로퍼티의 집합인 객체이다.

  • 이때 props가 없으면 빈 객체로 나온다. props인수는 그대로 두지만 props 속성이 없으면 빈 객체로 나올 뿐이다.

  • props의 프로퍼티가 외부에서 변하면 해당 변경 사항도 setup 메서드에 반영되고 이를 마크업까지 반영하고 싶다면 computed메서드를 사용하여 props 변경 사항을 인식하고 return 값을 다시 계산하도록 해야한다.

  • 즉, props는 기본적으로 반응형이긴 하다. 개별 값에 대해서가 아니라 props라는 객체 전체에 관해서말이다.
    따라서 속한 프로퍼티 중 하나라도 변경되면 Vue가 이를 알아차리고 props에 의존하는 모든 코드를 재실행한다.

context

  • 앞서 setup 메서드에는 2가지 인수가 있고 첫번째가 props라고 하였다.
    2번째가 바로 context이다.

  • 두 번째 인수인 context는 항상 Vue가 입력한다.

  • 이 해당 객체를 보면 3가지 속성을 알 수 있는데

attr

  • fall through 속성을 표시한다.
    우선 이 fall through 동작을 확인하려면 node를 반드시 1개로 통일시켜줄 필요가 있다.
    그리고 실행해보면

  • 폴스루와 같이 정의되지 않은 프로퍼티가 표시된다.

slots

<template>
  <div>
  <h2>{{ uName }}</h2>
    <slot></slot>
  <h2>{{ uName }}</h2>
  </div>
</template>
  • slots로는 컴포넌트에 있는 슬롯 데이터에 액세스할 수 있다.
  • slot 프로퍼티를 통해 프로그래밍 방식으로 액세스할 수 있다.

emit

  • emit은 함수로 커스텀 이벤트를 발생(emit)시키고자 할 때 호출 가능하다.
    이는 this. 키워드를 사용할 수 없기 때문에 this.$emit => context.emit으로 접근하는 것이다.

Provide

  • provide 함수는 2가지 인수를 필요로 하는데 첫번째로 key이다.
    그리고 두 번째 매개변수로 전달하고자 하는 실제 값이 들어간다.

  • 이 Provide의 특징은 여기서 ref를 사용하기 때문에 이후 이를 주입할 장소는 자동으로 업데이트되며
    이것이 장점으로 value의 변경 사항에 대해 인식한다는 점이다.

<script setup>
import {computed, provide, reactive} from "vue";

const user = reactive({name:'alex',age:27})
const uName = computed(()=>{
  return firstName.value + ' ' + lastName.value;
})
provide('userAge',user.age)
</script>

inject

<template>
  <div>
  <h2>{{ age }}</h2>
  </div>
</template>
<script>
import {inject} from "vue";

export default {
  props: ['userName'],
  setup(props, context) {
    const age = inject('userAge')
    // age.value = 99			<= 이 코드를 적어넣으면 안 됨
    return {age}
  },

}
</script>
  • 그리고 inject받아온 컴포넌트에서 임의로 변경해서도 안 된다. 왜냐하면 어디서 변경되었는지 확인하기가 어렵기 때문이다.
    나중에 까먹고 일일이 컴포넌트 확인해가면서 돌아다녀야하는 수고를 하고싶지 않다면 말이다.
    따라서 inject받아온 값의 변경은 provide를 한 곳에서 하는 것을 권장한다.
profile
智(지)! 德(덕)! 體(체)!

0개의 댓글