[vuejs] Component 기초 - template, render, setup, slot
leteu
·2023. 3. 4. 21:17
컴포넌트는 Vue에서 가장 기초가 되는 부분이다.
컴포넌트 하나 잘 만들어두면 비슷한 화면은 계속 가져다 쓸 수 있다.
Vue 3를 기준으로 작성하였다.
#1 참고
https://kr.vuejs.org/v2/guide/components.html
일단 공식 문서를 보자. 답은 저기에 있다.
결론만 보고 싶다면 넘어가자
#2 화면
일단 제일 중요한 건 화면이다.
일단 뭐가 보여야 재밌으니 화면부터 들어가겠다.
Template, Setup, Render 이렇게 3곳 중 한 군대를 골라서 화면을 만들어줄 수 있다.
## template
- 제일 익숙한 html로 짤 수 있다.
- pug 언어로도 가능하다. ( 이 포스트에선 다루지 않는다 )
<template>
<!-- 여기에 html 짜면 화면에 나온다 -->
<div></div>
</template>
<script>
import { defineComponent } from 'vue'
export default defineComponent({
setup() {
},
})
</script>
## render
- vue3에서 vue2와 문법이 바뀐 녀석이다.
- h 함수를 vue에서 임포트 해와서 코드를 짤 수 있다.
- 쓸 때 template은 지우고 써야 한다. 걔가 우선순위가 더 높다.
h 함수는 React의 createElement와 매우 유사하다.
<script>
import { defineComponent, h } from 'vue'
export default defineComponent({
setup() {
},
render() {
return h(
'div',
{
// 어트리뷰트
},
() => [
// 하위 컴포넌트
]
)
}
})
</script>
## setup
- 여기서도 할 수는 있다. 근데 보통 여기서는 사용할 데이터를 선언해야 해서 잘 안 쓴다. 알아만 두자
- template과 render는 지우고 사용하자
- 웬만해선 여기선 하지 말자
- 문법은 render와 같이 h 함수를 임포트 해와서 쓴다.
<script>
import { defineComponent, h } from 'vue'
export default defineComponent({
setup() {
return () => h(
'div',
{
// 어트리뷰트
},
() => [
// 하위 컴포넌트
]
)
},
})
</script>
#3 컴포넌트 사용
컴포넌트를 만들어 놔도 불러오지 않으면 화면에 뿌릴 수 없다.
전체적으로 사용하는 컴포넌트는 전역으로 처리하고 아닐 경우에 아래 코드처럼 하나하나 import 해와서 사용해주면 된다.
// component.vue
<template>
<!-- 여기에 html 짜면 화면에 나온다 -->
<div></div>
</template>
<script>
import { defineComponent } from 'vue'
export default defineComponent({
setup() {
},
})
</script>
// index.vue
<template>
<ComponenetVue />
</template>
<script>
import { defineComponent } from 'vue';
import ComponenetVue from './Component.vue';
export default defineComponent({
component: {
ComponenetVue
},
setup() {
},
})
</script>
이렇게 vue 파일을 import 하여 컴포넌트를 사용해줄 수 있다.
JSX로 짠 js/ts 컴포넌트 파일도 동일하게 불러와서 사용해 주면 된다.
# Slot
https://v3.ko.vuejs.org/guide/component-slots.html
얘가 잘 쓰진 않지만 이해하고 있으면 활용하기 좋은 친구다.
// component.vue
<template>
<div>
<slot name="content">
</div>
</template>
// index.vue
<template>
<ComponentVue>
<template v-slot:content>
<!-- 여기에 적으면 컴포넌트 안에 적힌다 -->
</template>
</ComponentVue>
</template>
<script>
import { defineComponent } from 'vue';
import ComponentVue from './Component.vue';
export default defineComponent({
component: {
ComponentVue
},
setup() {
},
})
</script>
이렇게 컴포넌트 안에 원하는 위치에 따로 커스텀이 가능하다.
컴포넌트의 재사용을 늘릴 수 있다.
## h (createElement)
slot 또한 h 랜더 함수에서 사용할 수 있다.
h 함수를 import 한 위치를 따라가다 보면 확인할 수 있다.
(아래 코드는 IDE에서 h함수에 f12 연타해서 나온 코드들이다.)
export declare function h(type: string, children?: RawChildren): VNode;
export declare function h(type: string, props?: RawProps | null, children?: RawChildren | RawSlots): VNode;
export declare function h(type: typeof Text_2 | typeof Comment_2, children?: string | number | boolean): VNode;
export declare function h(type: typeof Text_2 | typeof Comment_2, props?: null, children?: string | number | boolean): VNode;
export declare function h(type: typeof Fragment, children?: VNodeArrayChildren): VNode;
export declare function h(type: typeof Fragment, props?: RawProps | null, children?: VNodeArrayChildren): VNode;
export declare function h(type: typeof Teleport, props: RawProps & TeleportProps, children: RawChildren): VNode;
export declare function h(type: typeof Suspense, children?: RawChildren): VNode;
export declare function h(type: typeof Suspense, props?: (RawProps & SuspenseProps) | null, children?: RawChildren | RawSlots): VNode;
export declare function h<P, E extends EmitsOptions = {}>(type: FunctionalComponent<P, E>, props?: (RawProps & P) | ({} extends P ? null : never), children?: RawChildren | RawSlots): VNode;
export declare function h(type: Component, children?: RawChildren): VNode;
export declare function h<P>(type: ConcreteComponent | string, children?: RawChildren): VNode;
export declare function h<P>(type: ConcreteComponent<P> | string, props?: (RawProps & P) | ({} extends P ? null : never), children?: RawChildren): VNode;
export declare function h(type: Component, props: null, children?: RawChildren | RawSlots): VNode;
export declare function h<P>(type: ComponentOptions<P>, props?: (RawProps & P) | ({} extends P ? null : never), children?: RawChildren | RawSlots): VNode;
export declare function h(type: Constructor, children?: RawChildren): VNode;
export declare function h<P>(type: Constructor<P>, props?: (RawProps & P) | ({} extends P ? null : never), children?: RawChildren | RawSlots): VNode;
export declare function h(type: DefineComponent, children?: RawChildren): VNode;
export declare function h<P>(type: DefineComponent<P>, props?: (RawProps & P) | ({} extends P ? null : never), children?: RawChildren | RawSlots): VNode;
children을 쓰는 곳에 그냥 h 함수나 h 함수의 배열을 쓰면 기본적으로 default 슬롯에 들어가게 된다.
따로 슬롯을 명시하여 사용하면 RawChildren 인터페이스가 아닌 RawSlots 인터페이스로 잡히게 된다.
h('예시 컴포넌트',
{
// 어트리뷰트
},
{
default: () => [
h( ... ),
],
'슬롯 name': () => [
h( ... ),
h( ... ),
]
}
)
슬롯명: () => h( ... ) 형태로 사용하면 vue JSX에서도 슬롯이 사용 가능하다.
다음 포스트에선 prop, emit을 다뤄볼 예정이다.
'프로그래밍 > Vuejs' 카테고리의 다른 글
[Vuejs] Expose로 ref에서 함수 꺼내 쓰기 (0) | 2023.11.24 |
---|---|
[Vue 3] Props, Emit (0) | 2022.03.17 |
[Vue] Quasar Vue UI framwork 소개 (1) | 2022.03.02 |
[Vue] Composition API - 주사위 만들기 예제 (0) | 2022.02.22 |
[Vue 3] 라우트 변경, 새로고침, 창 닫기 감지 (0) | 2022.02.17 |