[Vuejs] Expose로 ref에서 함수 꺼내 쓰기

leteu

·

2023. 11. 24. 16:32

 

사실 expose 하는 방법에 대한 글이라기 보단

typescript로 작성할 때 자동완성 때문에  글 쓰게 됨

난 vscode 쓰기 때문에 jetbrains에서는 원래 잘 나오고 있는지는 모른다.

그래도 그냥 이렇게 해라

https://leteu.dev/posts/vue-expose


#1 일단 하는 방법

 

간단하다. 우선 setup 써서 하는 놈 먼저

...

<script setup lang="ts">
import { ..., defineExpose } from 'vue'
...

function something() {
	console.log('to do')
}

defineExpose({ something })
</script>

...

 

optional API는 

...
expose: ['something'],
...

 

 이렇게 해주면 끝이다.

 

이제 사용 방법이다.

 

#2 어떻게 쓰냐

위에서 작성한 Component를 `Child` 컴포넌트라고 하고 시작하겠다.

 

...
import Child from 'src/components/path/to/ChildComponent.vue'

const ChildRef = ref<typeof Child>()

function onClick() {
	ChildRef.value?.something()
    
    // 이러면 console에 `to do`라고 나올 거임
}

 

이렇게 작성하면 실행은 될거다.

 

그런데 문제가 생겼다. 아주 `빅 이슈`다.

 

something이라는 method가 자동완성도 안되고 마우스를 얹어봐도 `any`라고만 나온다.

내가 기대한 건`() => void`인데...

멋이 없다..

 

#3 멋 생성

애초에 import 저렇게 해오는 거부터 멋이 없다. 저거 먼저 해결해 보자.

 

// src/components/path/to/index.ts

export { default as Child } from './ChildComponent.vue'

 

ChildComponent가 있는 폴더에서 저렇게 index.ts 파서 export 해주자

 

...

<script setup lang="ts">
...

import { Child } 'src/components/path/to'

...

 

이렇게 들고 올 수 있다. 벌써 멋있다.

하지만 이 글을 작성하게 된 이유인 내가 만든 멋있는 함수가 `any`라고 나오는 문제가 남아있다.

 

index.ts를 이렇게 수정해 주자

 

// src/components/path/to/index.ts

import { default as Child } from './ChildComponent.vue'

type Child = InstaceType<typeof Child>

export {
	//
    Child,
}

 

이제 Child 컴포넌트를 사용하는 부모 vue 파일에서도 코드를 약간 수정해 준다.

 

...
import { Child } from 'src/components/path/to'

const ChildRef = ref<Child>()

 

아까 typeof Child라고 적어준 Ref의 타입 부분에 그냥 Child라고만 적어준다.

위에 index.ts에서 Child컴포넌트의 alias로 타입을 알려주었기 때문에 가능하다.

 

이제 자동 완성도 잘 되고 타입 툴팁도 잘 뜨고 멋있다.