Template Refs
뷰의 선언적인 렌더링 모델이 대부분의 직접적으로 DOM을 다루는 작업을 추상화했지만, 여전히 근본적인 돔 엘리먼트에 직접적으로 접근해야 하는 경우가 있다. 그래서, 특별한 ref 어트리뷰트를 사용할 수 있다.
<input ref="input">
ref는 v-for챕터에서 다뤘던 key 어트리뷰트와 비슷한 특별한 어트리뷰트다. 특정한 톰 엘리먼트나 또는, 마운트한 자식 컴포넌트 인스턴스로 부터 직접적인 참조를 얻도록 해준다. 이건 필요할 때 매우 유용한데, 예를 들면, 프로그래밍적으로 마운트된 컴포넌트의 input에 포커스를 맞추거나, 엘리먼트에 써드 파티 라이브러리를 초기화 할 때 등이다.
Refs에 접근하기
Composition API에서 참조를 얻기 위해, 같은 이름으로 ref를 선언해야 한다:
<script setup>
import { ref, onMounted } from 'vue'
// 엘리먼트 참조를 갖기 위해 ref를 선언해야 함
// template ref 값과 이름이 일치해야함
const input = ref(null)
onMounted(() => {
input.value.focus()
})
</script>
<template>
<input ref="input" />
</template>
<script setup>을 안쓰면, setup()의 ref도 같이 리턴해야만 한다:
export default {
setup() {
const input = ref(null)
// ...
return {
input
}
}
}
컴포넌트가 마운트된 이후에만 ref에 접근할 수 있음을 기억해라. 템플릿 표현식에서 input에 접근하길 시도하면, 첫 렌더링 에서는 null 일거다. 그건 엘리먼트가 첫 렌더가 끝나기 전까지 존재하지 않기 때문이다.
만약 template ref의 변화를 보고 싶다면, ref가 null 값을 가진 경우를 세어봐라.
watchEffect(() => {
if (input.value) {
input.value.focus()
} else {
// 아직 마운트되지 않거나, 엘리먼트가 언마운트 됨 (예; v-if)
}
})
v-for 안에있는 Refs
// 3.2.25나 그 이상 버전이 필요함
ref가 v-for안에서 사용될 때는, 대응하는 ref가 마운트 이후에 엘리먼트들이 채워지는 배열값을 담고 있을 수 있다:
<script setup>
import { ref, onMounted } from 'vue'
const list = ref([
/* .... */
])
const itemRefs = ref([])
onMounted(() => console.log(itemRefs.value))
</script>
<template>
<ul>
<li v-for="item in list" ref="itemRefs">
{{ item }}
</li>
</ul>
</template>
알아둬야 할건, ref 배열은 소스 배열의 같은 순서를 보장하지 않는다.
Function Refs
string key 대신에, ref 어트리뷰트는 함수에 바인딩될 수 있다. 이 ref 어트리뷰트는 각각의 컴포넌트가 업데이트 되었을 때 호출되며, 엘리먼트 참조를 저장할 위치에 대한 유연함을 준다. 함수는 첫번째 아규먼트를 엘리먼트 참조로 받는다.:
<input :ref="(el) => {/* el을 프로퍼티나 ref에 배정한다 */ }">
동적인 :ref 바인딩을 사용해서 ref 이름 문자열 대신에 함수를 넘길 수 있다. 엘리먼트가 언마운트 되면 아규먼트는 null이다. 물론, 인라인 함수대신에 메소드를 쓸 수도 있다.
컴포넌트에서 Ref
ref는 child 컴포넌트에서도 사용될 수 있다. 이 경우에 참조는 컴포넌트 인스턴스의 참조가 된다:
<script setup>
import { ref, onMounted } from 'vue'
import Child from './Child.vue'
const child = ref(null)
onMounted(() => {
// child.value는 <Child />의 인스턴스를 홀딩함
})
</script>
<template>
<Child ref="child" />
</template>
만약 child component가 <script setup>을 안쓰고 Options API를 쓰면, 참조되는 인스턴스는 차일드 컴포넌트의 this와동일할 것이다. 이 this는 부모 컴포넌트가 자식 컴포넌트의 모든 프로퍼티와 메소드에 접근할 수 있다는 것을 가르킨다. 이건 부모 자신간에 강력한 결합을 만들기 쉽다. 그래서 컴포넌트 refs는 틀림없이 필요한 경우에만 사용해야 한다. - 대부분의 경우에서 부모/ 자식의 상호작용은 기본적인 props와 emit인터페이스로 먼저 구현을 시도할 수 있다.
예외적으로, <script setup>을 사용하는 컴포넌트는 기본적으로 private 이다: <script setup>을 사용하는 자식 컴포넌트를 참조하는 부모 컴포넌트는 자식 컴포넌트가 defineExpose 매크로를 사용해서 public 인터페이스를 선택적으로 노출하기 전에는 아무것도 접근할 수 없다.
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
defineExpose({
a,
b
})
</script>
부모가 template refs를 통해서 컴포넌트의 인스턴스를 얻었을 때, 찾은 인스턴스는 { a: number, b: number }형태일 것이다.(refs는 자동적으로 노말 인스턴스처럼 언래핑된다.)
'front > vue' 카테고리의 다른 글
[vue3 공식문서 번역]Components.1.Registration (0) | 2022.04.28 |
---|---|
[vue3 공식문서 번역]Essentials.13.Components Basics (0) | 2022.04.28 |
[vue3 공식문서 번역]Essentials.11.Watchers (0) | 2022.04.27 |
[vue3 공식문서 번역]Essentials.10.Lifecycle Hooks (0) | 2022.04.25 |
[vue3 공식문서 번역]Essentials.9.Form Input Bindings (0) | 2022.04.25 |
댓글