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 |
댓글