Vue3 공식문서를 참고했습니다. 제 영어 실력 부족으로 인해 번역이 매끄럽지 않은 부분이 있을 수 있습니다..
<script setup>
??
<script setup>
은 SFC ( Single File Component ) 내에서 컴포지션 API 를 사용하기 위한 컴파일 타임 Syntax sugar ( 더 쉽게 읽고 표현할 수 있도록 설계된 코드 ) 입니다.
SFC 와 컴포지션 API 를 모두 사용하는 경우 권장되며, 일반 <script>
구문과 많은 차이점이 있습니다.
- 더 적은 상용구로 더 간결한 코드
- 순수 TypeScript를 사용하여 props 및 emit 이벤트를 선언하는 기능
- 향상된 Runtime 성능 ( 템플릿은 중간 프록시 없이 동일한 범위의 렌더 함수로 컴파일 )
- 향상된 IDE 타입 추론 성능 ( 언어 서버가 코드에서 유형을 추출하는 작업 감소)
기본 구문
<script setup>
console.log('hello script setup')
</script>
내부 코드는 구성 요소 setup() 기능의 내용으로 컴파일됩니다. 다시말해, <script>
구성 요소를 처음 가져올 때는 한 번만 실행되는 normal 과 달리 구성 요소의 인스턴스가 생성될 때마다 <script setup>
의내부 코드가 실행됩니다.
최상위 바인딩은 템플릿에 노출됩니다.
<script setup>
을 사용할 때 내부에 선언된 모든 최상위 바인딩 (변수, 함수 선언 및 import 포함 ) 은 템플릿에서 직접 사용할 수 있습니다.
<script setup>
// variable
const msg = 'Hi!'
// functions
function log() {
console.log(msg)
}
</script>
<template>
<div @click="log">{{ msg }}</div>
</template>
import 도 같은 방식으로 노출됩니다. methods
옵션을 통해 노출하지 않고도 템플릿 표현식에서 가져온 Helper 함수를 직접 사용할 수 있습니다.
<script setup>
import { capitalize } from './helpers'
</script>
<template>
<div>{{ capitalize('hi') }}</div>
</template>
반응성 (Reactivity)
반응성 API 를 사용하여 반응성 상태를 명시적으로 생성해야 합니다. setup()
함수에서 반환된 값과 유사하게 ref 는 템플릿에서 참조될 때 자동으로 unwrapping 됩니다.
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
컴포넌트 사용
<script setup>
범위안의 값은 사용자 정의 구성 요소 태그 이름으로 직접 사용할 수 있습니다.
<script setup>
import MainComponent from './MainComponent.vue'
</script>
<template>
<MainComponent />
</template>
케밥케이스도 정상적으로 작동하지만 일관성을 위해 파스칼케이스를 사용하는 것이 좋습니다.
동적 컴포넌트
컴포넌트는 문자열 키 아래에 등록되는 대신 변수로 참조되므로 <script setup>
내부에서 동적 컴포넌트를 사용할 때 동적 바인딩 :is
을 사용해야 합니다.
<script setup>
import Foo from './Foo.vue'
import Bar from './Bar.vue'
</script>
<template>
<component :is="Foo" />
<component :is="someCondition ? Foo : Bar" />
</template>
재귀 구성 요소
SFC는 파일 이름을 통해 암시적으로 자신을 참조할 수 있습니다. 예를 들어 FooBar.vue
파일은 템플릿에서 <FooBar/>
와 같이 자신을 참조할 수 있습니다.
아래 코드의 FooBar 는 import된 컴포넌트보다 우선 순위가 낮습니다. 컴포넌트의 유추된 이름과 충돌하는 import가 있는 경우 import 에 alias 를 지정할 수 있습니다.
import { FooBar as FooBarChild } from './components'
Namespaced 컴포넌트
개체 속성 아래에 중첩된 컴포넌트를 참조하기 위해 <Foo.Bar>
처럼 점과 함께 컴포넌트 태그를 사용할 수 있습니다.
단일 파일에서 여러 컴포넌트를 import 할 때 유용합니다.
<script setup>
import * as Form from './form-components'
</script>
<template>
<Form.Input>
<Form.Label>label</Form.Label>
</Form.Input>
</template>
Using Custom Directives ( 커스텀 디렉티브 사용)
전역으로 등록된 사용자 정의 디렉티브는 예상대로 작동하며, 컴포넌트에 대해 위에서 설명한 것처럼 로컬 디렉티브를 템플릿에서 직접 사용할 수 있습니다.
하지만 한 가지 제한 사항이 있습니다. vNameOfDirective
템플릿에서 직접 사용할 수 있도록 하려면 다음 스키마에 따라 로컬 사용자 정의 디렉티브의 이름을 지정해야합니다.
<script setup>
const vMyDirective = {
beforeMount: (el) => {
// do something with the element
}
}
</script>
<template>
<h1 v-my-directive>This is a Heading</h1>
</template>
<script setup>
// imports also work, and can be renamed to fit the required naming schema
import { myDirective as vMyDirective } from './MyDirective.js'
</script>
defineProps 와 defineEmits
<script setup>
내부에 props
와 emits
를 선언하기 위해서는 defineProps
와 defineEmits
API 를 사용해야 합니다. 이것은 전체 타입추론을 지원하고 <script setup>
내부에서 자동으로 사용할 수 있게 해줍니다.
<script setup>
const props = defineProps({
foo: String
})
const emit = defineEmits(['change', 'delete'])
// setup code
</script>
defineProps
와defineEmits
는<script setup>
내에서만 사용할 수 있는 컴파일러 매크로입니다. 이것들은 import 할 필요가 없으며<script setup>
이 처리될 때 컴파일됩니다.defineProps
는 props 옵션과 동일한 값을 허용하고,defineEmits
는 emits 옵션과 동일한 값을 허용합니다.defineProps
및defineEmits
는 전달된 옵션을 기반으로 적절한 타입 추론을 제공합니다.defineProps
및defineEmits
에 전달된 옵션이 설정에서 모듈 범위로 호이스트됩니다. 따라서 옵션은 설정 범위에 선언된 지역 변수를 참조할 수 없으며 컴파일 오류가 발생합니다.- 하지만 import된 바인딩은 모듈 범위에 있으므로 참조할 수 있습니다.
TypeScript 를 사용하는 경우에는 pure type 주석을 이용해 props
와 emits
를 선언할 수 있습니다.
defineExpose
<script setup>
을 사용하는 컴포넌트는 default 에 의해 종료됩니다. 즉, 템플릿 ref 또는 $parent chain 을 통해 검색되는 컴포넌트의 공개 인스턴스는 <script setup>
내부에 선언된 바인딩을 노출하지 않습니다.
<script setup>
컴포넌트의 속성을 명시적으로 표시하려면 defineExpose 컴파일러 매크로를 사용하세요
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
defineExpose({
a,
b
})
</script>
부모가 템플릿 ref를 통해 이 컴포넌트의 인스턴스를 가져오면 검색된 인스턴스는
{ a: number, b: number }
모양입니다. (ref는 일반 인스턴스와 마찬가지로 자동으로 래핑 해제됩니다).
useSlot 와 useAttrs
템플릿엥서 $slots 와 $attrs로 직접 접근할 수 있으므로 <script setup>
내부의 slot 과 attr 사용은 드물어야합니다.
필요한 경우에는 useSlot 과 useAttrs Helpers 를 각각 사용합니다.
<script setup>
import { useSlots, useAttrs } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
</script>
useSlots 와 useAttrs 는 setupContext.slot, setupContext.attrs 와 동등한 값을 반환하는 실제 런타임 함수입니다. 일반 컴포지션 API 기능에서도 사용가능합니다.
일반 <script>
와 함께 사용
<script setup>
은 일반적인 <script>
와 함께 사용할 수 있습니다. 아래와 같은 경우 일반적인 <script>
가 필요할 수도 있습니다.
예를 들어 inheritAttrs 또는 플러그인을 통해 활성화된 사용자 지정 옵션과 같이
<script setup>
에서 표현할 수 없는 옵션을 선언하는 경우.named exports 를 선언합니다.
side effect 를 실행하거나 한 번만 실행해야 하는 개체를 만듭니다.
<script>
// normal <script>, executed in module scope (only once)
runSideEffectOnce()
// declare additional options
export default {
inheritAttrs: false,
customOptions: {}
}
</script>
<script setup>
// executed in setup() scope (for each instance)
</script>
Top-Level await
Top-level await 는 <script setup>
내에서 사용할 수 있습니다. 결과 코드는 비동기 setup() 으로 컴파일 됩니다.
const post = await fetch(`/api/post/1`).then(r=>r.json())
또한 await 표현식은 await 후 현재 컴포넌트의 인스턴트 컨텍스트를 보존하는 형식으로 자동으로 컴파일 됩니다.
'Study > Vue' 카테고리의 다른 글
Vue 3 ) TodoApp 제작 (0) | 2022.01.12 |
---|---|
Vue 3 ) Vite 2로 생성한 프로젝트에 TailwindCSS 적용하기 (0) | 2022.01.11 |
Vue 3 ) Ref, Refs ?? (0) | 2022.01.09 |
Vue 3 ) Vue3 에서 제공하는 반응성과 관련된 APIs (0) | 2022.01.09 |
Vue 3 ) Provide ? (0) | 2022.01.09 |
댓글