HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
💌
JJong’s Archive
/
🏞️
Vue
/
Vue Compositions

Vue Compositions

Select
Dec 1, 2023
  • 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 적용하기
  1. npm create vite@latest . 로 ts vue 프로젝트를 생성
  1. ESLint, Prettier 적용
      • eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier eslint-plugin-prettier eslint-config-prettier eslint-plugin-vue 를 개발 의존성으로 설.p치
      • .eslintrc
        • { "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin: prettier/recommended", "plugin:vue/vue3-recommended" ], "parserOptions": { "parser": "@typescript-eslint/parser" } }
      • .prettierrc
        • { "semi": false, //세미콜론 x "singleQuote": true, //작은 따옴표만 "endOfLine": "lf", //파일의 마지막 줄은 항상 줄바꿈 "trailingComma": "none", //문장 끝에 세미콜론 x, "singleAttributePerLine": true, //속성당 한 줄 "bracketSameLine": true, //브라켓은 줄바꿈 되지 않음 }
 
 

Options API ⇒ Compositions API

 
  1. data() ⇒ const val = ref(초기값)
      • ref는 참조 객체. script 안에서는 value 속성으로 데이터를 얻어야 함
      • template안에서는 ref만 써도 됨
      <script setup lang=”ts”> import { ref } from 'vue' const count = ref(0) </script> <template> <h1>{{ count }}</h1> </template>

      reactive

      • data가 참조형일 때 쓸 수 있는 반응형 데이터
      • ref와 차이점
          1. data를 .value없이 그냥 사용할 수 있음
          1. 요소의 변경까지 watch하고 싶을 때, deep:true를 적용하지 않아도 됨
      const user = reactive({ name: 'jjong', age: 12 }) console.log(user.name) //user.value.name xx watch(user, (newVal) => { //세번째 속성으로 deep:true가 없어도 속성만 변경시 watch가 동작 console.log(newVal) })
       
  1. methods ⇒ 일반함수나 화살표 함수 형태
    1. <script setup lang=”ts”> .. function increase() { count.value += 1 } </script> <template> <h1 @click="increase">{{ count }}</h1> </template>
 
  1. lifecycle
    1. created() ⇒ script 내부에 바로 코드 추가
      1. <script setup lang=”ts”> console.log("created!") </script>
    2. mounted() ⇒ onMounted 안에 콜백 함수에 코드 추가
      1. <script setup lang=”ts”> import { onMounted } from 'vue' onMounted(() => { console.log("Mounted!") }) </script>
         
  1. computed ⇒ computed 안에 콜백 함수에 반환값
    1. <script setup lang=”ts”> import { computed } from 'vue' .. const double = computed(() => count.value*2) </script> <template> <h1>{{ double }}</h1> </template>
      • getter, setter ⇒ get, set의 객체 속성으로
        • <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>
 
  1. watch ⇒ watch 함수
    1. watch(count, (newVal, oldVal) ⇒ { //newval, oldval은 선택 console.log(oldVal + " -> " + newVal) })
      • 대상 데이터가 객체일 때, watch 함수의 세번째 속성으로 {deep: true}를 주면 객체의 속성만 변경 시에도 watch함수가 동작
        • watch(user, (newVal) ⇒ { console.log(newVal) }, { deep: true })
      • 아예 객체 속성을 watch하고 싶다면 ? ⇒ 첫번째 매개변수로 해당 속성을 반환하는 함수를 넘겨주기!
        • watch( () => user.value.name, (newVal) ⇒ { console.log(newVal) } )
       
  1. component ⇒ script에서 import 하고 template에서 바로 쓰면 됨
    1. <script setup lang="ts"> import HelloWorld from './components/HelloWorld.vue' </script> <template> <HelloWorld msg="Vite + Vue" /> </template>
 
  1. props ⇒ defineProps
    1. <script> defineProps<{ modelValue: string // == required: true name?: string // == required: false active?: boolean }>() </script>
      • default 속성을 주고 싶다면? ⇒ withDefaults두번째 인자로 기본값을!
      <script> withDefaults( defineProps<{ modelValue: string // == required: true name?: string // == required: false active?: boolean }>(), { name: '', active: false } ) </script>
      • props를 스크립트에서 쓰고 싶다면 ⇒ withDefaults나 defineProps를 변수로 받아서 사용
      const props1 = withDefaults(.. const props2 = defineProps<{.. console.log(props1.name) console.log(props2.active)
       
  1. emits ⇒ defineEmits
    1. <script> const emit = defineEmits(['update:modelValue']) //emit 등록 => 함수에서 씀 // template에서 인라인으로 $emit을 호출하는 대신, modelValue 업데이트하는 함수를 따로 만듦 function inputHandler(event: Event) { emit('update:modelValue', (event.target as HTMLInputElement).value) //null이라는 경고 표시 제거 위해 타입 단언 } </script>
       
  1. inheritAttrs ⇒ defineOptions({inheritAttrs})
      • inheritAttrs: 컴포넌트를 호출할 때 넘겨주는 props를 해당 컴포넌트의 최상위 요소가 모두 넘겨 받을지 여부를 결정하는 옵션(기본 값은 true)
      • defineOptions : inheritAttrs외에도 컴포넌트의 속성들을 여기서 지정하면 됨
      defineOptions({inheritAttrs: false})
      • 넘겨지는 모든 속성 ⇒ useAttrs()
        • optionsAPI에서 $attrs로 접근한 것
        • import { useAttrs } from 'vue' const attrs = useAttrs()
       
  1. (html 요소에 접근할 때 쓰는)ref ⇒ ref 쓰고, 같은 이름의 변수를 선언해줘야 함
    1. <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>