- vue는 options API와 Compositions API 두가지 버전으로 제공된다
- Compositions API: ts에 더 친화적, 복잡한 프로젝트에 적합
- options API: ts를 지원하지만 덜 친화적, 단순한 프로젝트에 적합(이전까지 이 방법으로 함)
- 두 API를 혼용해서 쓸 수도 있다
- 기본적으로 template 부분은 두 API 동일하고, script 부분에 차이가 있다
- Compositions API 사용 방법
- 컴포넌트의 script를
<script setup lang=”ts”>
로 표시 - setup : compositions API라는 뜻
- 이를 통해 export default 블럭을 쓰지 않아도 됨
- lang=”ts” : 말그대로.. js가 아닌 ts라는 뜻
(참고) vite로 vue 프로젝트 생성 & ESLint, Prettier 적용하기
- ESLint, Prettier 적용
-
eslint
@typescript-eslint/parser @typescript-eslint/eslint-plugin
prettier
eslint-plugin-prettier
eslint-config-prettier
eslint-plugin-vue
를 개발 의존성으로 설.p치 - .eslintrc
- .prettierrc
{ "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin: prettier/recommended", "plugin:vue/vue3-recommended" ], "parserOptions": { "parser": "@typescript-eslint/parser" } }
{ "semi": false, //세미콜론 x "singleQuote": true, //작은 따옴표만 "endOfLine": "lf", //파일의 마지막 줄은 항상 줄바꿈 "trailingComma": "none", //문장 끝에 세미콜론 x, "singleAttributePerLine": true, //속성당 한 줄 "bracketSameLine": true, //브라켓은 줄바꿈 되지 않음 }
Options API ⇒ Compositions API
- data() ⇒
const val = ref(초기값)
- ref는 참조 객체. script 안에서는
value
속성으로 데이터를 얻어야 함 - template안에서는 ref만 써도 됨
- data가 참조형일 때 쓸 수 있는 반응형 데이터
- ref와 차이점
- data를 .value없이 그냥 사용할 수 있음
- 요소의 변경까지 watch하고 싶을 때, deep:true를 적용하지 않아도 됨
<script setup lang=”ts”> import { ref } from 'vue' const count = ref(0) </script> <template> <h1>{{ count }}</h1> </template>
reactive
const user = reactive({ name: 'jjong', age: 12 }) console.log(user.name) //user.value.name xx watch(user, (newVal) => { //세번째 속성으로 deep:true가 없어도 속성만 변경시 watch가 동작 console.log(newVal) })
- methods ⇒ 일반함수나 화살표 함수 형태
<script setup lang=”ts”> .. function increase() { count.value += 1 } </script> <template> <h1 @click="increase">{{ count }}</h1> </template>
- lifecycle
- created() ⇒ script 내부에 바로 코드 추가
- mounted() ⇒
onMounted
안에 콜백 함수에 코드 추가
<script setup lang=”ts”> console.log("created!") </script>
<script setup lang=”ts”> import { onMounted } from 'vue' onMounted(() => { console.log("Mounted!") }) </script>
- computed ⇒
computed
안에 콜백 함수에 반환값 - getter, setter ⇒ get, set의 객체 속성으로
<script setup lang=”ts”> import { computed } from 'vue' .. const double = computed(() => count.value*2) </script> <template> <h1>{{ double }}</h1> </template>
<script setup lang="ts"> .. const double = computed({ get() { return count.value * 2 }, set(newVal) { count.value = newVal / 2 } }) const assign = () => { double.value = 8 //double의 setter 실행 } </script>
- watch ⇒
watch
함수 - 대상 데이터가 객체일 때, watch 함수의 세번째 속성으로 {deep: true}를 주면 객체의 속성만 변경 시에도 watch함수가 동작
- 아예 객체 속성을 watch하고 싶다면 ? ⇒ 첫번째 매개변수로 해당 속성을 반환하는 함수를 넘겨주기!
watch(count, (newVal, oldVal) ⇒ { //newval, oldval은 선택 console.log(oldVal + " -> " + newVal) })
watch(user, (newVal) ⇒ { console.log(newVal) }, { deep: true })
watch( () => user.value.name, (newVal) ⇒ { console.log(newVal) } )
- component ⇒ script에서 import 하고 template에서 바로 쓰면 됨
<script setup lang="ts"> import HelloWorld from './components/HelloWorld.vue' </script> <template> <HelloWorld msg="Vite + Vue" /> </template>
- props ⇒
defineProps
- default 속성을 주고 싶다면? ⇒
withDefaults
두번째 인자로 기본값을! - props를 스크립트에서 쓰고 싶다면 ⇒ withDefaults나 defineProps를 변수로 받아서 사용
<script> defineProps<{ modelValue: string // == required: true name?: string // == required: false active?: boolean }>() </script>
<script> withDefaults( defineProps<{ modelValue: string // == required: true name?: string // == required: false active?: boolean }>(), { name: '', active: false } ) </script>
const props1 = withDefaults(.. const props2 = defineProps<{.. console.log(props1.name) console.log(props2.active)
- emits ⇒
defineEmits
<script> const emit = defineEmits(['update:modelValue']) //emit 등록 => 함수에서 씀 // template에서 인라인으로 $emit을 호출하는 대신, modelValue 업데이트하는 함수를 따로 만듦 function inputHandler(event: Event) { emit('update:modelValue', (event.target as HTMLInputElement).value) //null이라는 경고 표시 제거 위해 타입 단언 } </script>
- inheritAttrs ⇒
defineOptions({inheritAttrs})
- inheritAttrs: 컴포넌트를 호출할 때 넘겨주는 props를 해당 컴포넌트의 최상위 요소가 모두 넘겨 받을지 여부를 결정하는 옵션(기본 값은 true)
- defineOptions : inheritAttrs외에도 컴포넌트의 속성들을 여기서 지정하면 됨
- 넘겨지는 모든 속성 ⇒
useAttrs()
- optionsAPI에서 $attrs로 접근한 것
defineOptions({inheritAttrs: false})
import { useAttrs } from 'vue' const attrs = useAttrs()
- (html 요소에 접근할 때 쓰는)ref ⇒ ref 쓰고, 같은 이름의 변수를 선언해줘야 함
<script> const inputEl = ref<HTMLInputElement | null>(null) //타입을 유니온으로 onMounted(()=> { if(inputEl.value) { inputEl.value.focus() } }) </script> <template> <input ref="inputEl" /> </template>
- 즉시 실행 함수 ⇒
;(함수)()
<script setup lang="ts"> ;(async ()=>{ const res = await fetch('api/hello') })() const json = await res.json() console.log(json) </script>