Can I use ... Vue 3?
๐Ÿ“„

Can I use ... Vue 3?

Created
Oct 31, 2021 04:43 PM
Tags
vue
web
javascript
refactoring
Conference
FEConf 2021
Video preview

Vue 3์˜ ๋“ฑ์žฅ

  • ๊ฐ•ํ™”๋œ Typescript ์ง€์›
    • ๋”์šฑ ์„ธ๋ถ„ํ™”๋œ ํƒ€์ž… ์„ ์–ธ
  • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•œ Composition API (setup)
  • Template ๋‚ด ์ตœ์ƒ์œ„ Element ๊ฐ€ ๋‘ ๊ฐœ ์ด์ƒ์ด ๋˜์–ด๋„ ๋จ
  • ๋“ฑ

Composition API

  • ์›๋ž˜๋Š” Vue 2์˜ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (@vue/composition-api)
  • ๋™์ผํ•œ Composition ์ฝ”๋“œ๋กœ Vue 2์™€ Vue 3 ๋‘˜ ๋‹ค ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅ

์‹ค๋ฌด์ž๊ฐ€ ๋ฐ”๋ผ๋ณธ Vue 3

  • ๊ทธ๋Ÿผ ๋ฐ”๋กœ ์ด๋ฅผ ์ ์šฉํ•ด์•ผ ํ• ๊นŒ? โ†’ ๊ทธ๊ฒƒ์€ ์•„๋‹˜
    • Vuetify, Vue-datepicker, Vue-lazyload ๋“ฑ
    • ์•„์ง๊นŒ์ง€ ์ œ๋Œ€๋กœ Vue 3๋ฅผ ์ง€์›ํ•˜๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฏธ๋น„
  • ๊ทธ๋Ÿผ ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋‘ ๊ฑท์–ด๋‚ด๊ณ  Vue 3๋กœ ๋‹ค์‹œ ์งœ๋ฉด ์–ด๋–จ๊นŒ
  • ์„œ๋น„์Šค ๊ฐœ๋ฐœ์— ์žˆ์–ด 2021๋…„์—๋Š” ์•„์ง Vue 2๊ฐ€ ์šฐ์„ธ (VueSchool)
    • ๋”ฐ๋ผ์„œ ์ž…๋ฌธ์ž๋Š” Vue 2๋ฅผ ๋จผ์ € ๊ณต๋ถ€ํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆํ•˜๋‹ค

์‹ค๋ฌด์ž์˜ ๊ณ ๋ฏผ

  • ๊ทธ๋Ÿผ ๊ทธ๋ƒฅ 2021๋…„์€ ๊ฐ€๋งŒํžˆ ์žˆ์–ด์•ผ ํ•˜๋‚˜?
    • Vue 2์˜ Composition API์™€ TypeScript๋ฅผ ๋จผ์ € ๋„์ž…ํ•ด๋ณด์ž
  • @vue/composition-api
    • Vue 2์—์„œ Components์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋กœ์ง์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์คŒ
    • ํ•จ์ˆ˜ ๊ธฐ๋ฐ˜์˜ API ์ž‘์„ฑ ๊ฐ€๋Šฅ์œผ๋กœ TS ์ถ”๋ก  ์ด์  ๊ทน๋Œ€ํ™”
    • Data, Logic ๋ชฉ์ (๋„๋ฉ”์ธ)๋ณ„๋กœ ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ ๊ฐ€๋Šฅ
    • React Hook ๋ฐฉ์‹์„ ์ฑ„ํƒ + ๋‹จ์  ๋ณด์™„
      • ๋ถ„๊ธฐ๋ฌธ, ๋ฐ˜๋ณต๋ฌธ, ์ค‘์ฒฉ ํ•จ์ˆ˜ ๋‚ด์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
      • ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ ์ฃผ๊ธฐ์— ๋”ฐ๋ผ ์ตœ์ดˆ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰
      • React Hook์€ State์˜ ๋ณ€ํ™”์— ๋”ฐ๋ผ ํ™”๋ฉด์ด ๋‹ค์‹œ ๊ทธ๋ ค์งˆ ๋•Œ, Hook์ด ๋‹ค์‹œ ์‹คํ–‰๋˜๊ฑฐ๋‚˜ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์กด์žฌ

@vue/composition-api ์˜ˆ์‹œ

// Vue 2 <template> <div> <p>{{ message }}</p> <button @click="changeMessage">Change</button> </div> </template> <script> import { ref } from '@vue/composition-api'; export default { setup() { const message = ref('hi'); const changeMessage = () => message.value = 'hi Vue 2'; return { message, changeMessage }; }, }; </script>
// Vue 3 <template> <div> <p>{{ message }}</p> <button @click="changeMessage">Change</button> </div> </template> <script> import { ref, defineComponent } from 'vue'; export default defineComponent({ setup() { const message = ref('hi'); const changeMessage = () => message.value = 'hi Vue 2'; return { message, changeMessage }; }, }); </script>
ย 
  • ๋‹ค๋งŒ Composition API๋กœ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ๋น„์ถ”์ฒœ
    • setup ์˜ ๋ชฉ์ ์€ ๊ทธ์ € '์žฌ์‚ฌ์šฉ์„ฑ'
    • ๋”ฐ๋ผ์„œ Composition API๋กœ ์ธํ•ด Vue ์˜ ์ƒ์‚ฐ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋Š” ๊ฒฝ์šฐ
    • ํ•ด๋‹น ๋กœ์ง์—์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. (= ์ƒ๊ฐ ์—†์ด ์‚ฌ์šฉํ•˜์ง€ ๋ง์ž)
  • ex) Modal์„ ์—ด๊ณ  ๋‹ซ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ์ค‘๋ณต๋˜๋Š” ๋กœ์ง์ด ์กด์žฌ โ†’ Composition API๋กœ ๋ถ„๋ฆฌ ๊ฐ€๋Šฅ

@vue/composition-api ์ฃผ์˜ ์‚ฌํ•ญ

  • ๊ธฐ์กด Mixin ๋˜๋Š” HOC ์ฝ”๋“œ ์žฌํ™œ์šฉ ๋ฐฉ์‹์€ ๊ฐ€๊ธ‰์  ์ง€์–‘
    • Vue JS ์ปค๋ฎค๋‹ˆํ‹ฐ ์ž์ฒด๊ฐ€ Composition API๋กœ ๋ฐฉํ–ฅ์„ ์ง„ํ–‰์ค‘
    • ์˜ˆ์ „ Mixin์ด๋‚˜ HOC๋Š” ๋” ์ด์ƒ ์œ ํšจํ•˜์ง€ ์•Š์Œ
    • ํŠนํžˆ Mixin๊ณผ Composition API๊ฐ€ ์„œ๋กœ ๋’ค์„ž์ธ ๊ฒฝ์šฐ, ๋””๋ฒ„๊น…์ด ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์Œ
    • ๊ธฐ์กด ์ฝ”๋“œ โ†’ Composition API ํ˜•ํƒœ๋กœ ์ ์ „์  ๊ฐœ์„  ์ถ”์ฒœ
  • TS์™€ ๊ฐ™์ด ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ํšจ๊ณผ ์ƒ์Šน
    • Hook(Composition)์—์„œ ์ •์˜ํ•œ ํŒŒ์ผ์„ ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ์žฌ์„ ์–ธ ํ–ˆ์„ ๋•Œ ์‹ค์ˆ˜๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์Œ
  • reactive API ๋ณด๋‹ค๋Š” ref API ์‚ฌ์šฉ์„์ง€ํ–ฅ
    • reactive ๋Š” ๊ฐ์ฒด๋ฅผ Reactivity ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” API
    • ์ด๋Š” ๋””๋ฒ„๊น…์„ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ
  • Vue 3์—์„œ ์ œ๊ณต๋˜๋Š” API๊ฐ€ ๋ชจ๋‘ ์ง€์›๋˜์ง€๋Š” ์•Š์Œ
    • Vue 2์˜ @vue/composition-api ๋Š” 95%์ •๋„ ์ง€์›๋œ๋‹ค ์ƒ๊ฐ

Vue 2์˜ TypeScript ์ง€์›

  • Class ๋ฌธ๋ฒ•๋ณด๋‹ค๋Š” Vue.extend() ๋ฅผ ์ด์šฉํ•œ ๊ฐ์ฒด ๋ฌธ๋ฒ• ์ง€ํ–ฅ
    • <script lang="ts"> import Vue from 'vue'; export default Vue.extend({ data: () => ({ message: '', }), methods: { changeMessage() { this.message = 10; // Type Error }, }, }); </script>
    • Vue 3 ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ์ˆ˜์›”
    • ์‰ฝ๊ฒŒ TypeScript ์ ์šฉ์ด ๊ฐ€๋Šฅ
  • tsconfig.json ํŒŒ์ผ์— noImplicitThis: true ์˜ต์…˜ ์ถ”๊ฐ€
    • SFC(Single File Component) ๋‚ด์—์„œ ํƒ€์ž… ์ถ”๋ก ์ด ์ •ํ™•ํ•˜๊ฒŒ ์ด๋ฃจ์–ด์ง
  • Computed ์†์„ฑ์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์€ ๋ฐ˜๋“œ์‹œ ์ •์˜
    • ์ •์˜ํ•˜์ง€ ์•Š์œผ๋ฉด ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ํƒ€์ž… ์ถ”๋ก ์ด ์ œ๋Œ€๋กœ ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์Œ
  • Store ๋“ฑ ๊ธฐํƒ€ ํƒ€์ž… ์ •์˜๋Š” d.ts ํŒŒ์ผ์— ์ •์˜
    • ์„ ์–ธ ํŒŒ์ผ์„ ํ•˜๋‚˜ ์ •์˜ํ•ด์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์— ์žˆ์–ด ์ข‹์Œ

๊ธฐ์กด Vue ํ”„๋กœ์ ํŠธ์— TS๋ฅผ ์ ์šฉํ•˜๋ ค๋ฉด?

  1. CLI ๋ช…๋ น์–ด๋กœ TS ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ถ”๊ฐ€ or ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋ฐ˜ ์ƒˆ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
      • ๋ฐœํ‘œ์ž๋Š” ํ›„์ž๋ฅผ ์ถ”์ฒœ
      • ํ˜ธํ™˜์„ฑ ํ™•๋ณด๋ฅผ ์œ„ํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „๋“ค์„ ๋งž์ถฐ์ค˜์•ผ ํ•˜๋Š”๋ฐ
      • ์ด ๋•Œ, ์•„์˜ˆ ์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข€ ๋” ์ˆ˜์›”ํ•˜๊ฒŒ ์ง„ํ–‰๋จ
  1. tsconfig.json ํŒŒ์ผ์— allowJS ๋ฐ noImplicitThis ์˜ต์…˜ ์ถ”๊ฐ€
      • allowJS : ํ•œ ๋ฒˆ์— ๋ชจ๋‘ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ์ ์ง„์ ์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๊ธฐ ์œ„ํ•จ
      • noImplicitThis : TS ์ƒ์‚ฐ์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•จ
  1. ๊ธฐ๋ณธ์ ์ธ Type Errors๋งŒ ์ˆ˜์ •ํ•˜๊ณ , any ์™€ ๊ฐ™์€ ์•ฝํ•œ ํƒ€์ž…๋ถ€ํ„ฐ ์ ์ง„์ ์œผ๋กœ ์ ์šฉ
      • TS ๋ณ€ํ™˜ ํ›„, JS ํŒŒ์ผ์—์„œ ์กฐ๊ธˆ์”ฉ ํƒ€์ž… ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ๋  ๊ฒƒ
      • ์ด ๋ถ€๋ถ„๋“ค์„ ์‹œ์ž‘์œผ๋กœ ์ ์ง„์ ์œผ๋กœ ํƒ€์ž…์„ ์ •์˜ํ•ด ๋‚˜๊ฐ
  1. npm run build ๊ฐ€๋Šฅํ•œ ์ˆ˜์ค€์˜ ํƒ€์ž… ์ •์˜ ๋ฐ ์ˆ˜์ •
      • ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…๋ณด๋‹ค๋Š” any ์™€ ๊ฐ™์€ ํƒ€์ž…๋“ค๋ถ€ํ„ฐ ์ •์˜
  1. strict ๋ ˆ๋ฒจ์„ ์˜ฌ๋ ค๊ฐ€๋ฉฐ ํšจ์šฉ์„ฑ์ด ๋†’์€ ๊ณณ์— ์ ์ง„์ ์œผ๋กœ ํƒ€์ž… ์ •์˜ ์ง„ํ–‰

์ •๋ฆฌํ•˜์ž๋ฉด

  • Vue 2์—์„œ๋„ Vue 3์˜ Composition API์™€ TypeScript ์‚ฌ์šฉ์ด ์ถฉ๋ถ„ํžˆ ๊ฐ€๋Šฅํ•˜๋‹ค
  • Vue 3๋Š” Core์™€ Community Ecosystem์ด ์ถฉ๋ถ„ํžˆ ์„ฑ์ˆ™ํ•ด์กŒ์„ ๋•Œ ๋„์ž…ํ•ด๋ณด์ž
    • ์•„๋งˆ IE ์ง€์›์ด ๋๋‚˜๋Š” 2022๋…„ 6์›” ์ดํ›„
  • ์‚ฌ์šฉ์ž ์ธต๊ณผ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ Vue 3๋ฅผ ์„ ์ œ์ ์œผ๋กœ ๋„์ž…ํ•ด๋ณผ ์ˆ˜ ์žˆ์Œ

๊ทธ ์™ธ ์‚ฌํ•ญ

VueUse (GitHub)

  • Vue 2์™€ Vue 3 ๋ชจ๋‘ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ Composition API ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • 148๊ฐœ Util API ์ง€์›
  • Web API, Animation, Electron, Firebase, Router, ...

ํŒ

  • VSC Vetur ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ "ts" + tab ๋‹จ์ถ•ํ‚ค๋ฅผ ์ด์šฉํ•ด .vue ํŒŒ์ผ ์ƒ์„ฑํ•˜๋ฉด ํŽธํ•˜๋‹ค
  • Props ์†์„ฑ์„ ๋จผ์ € ์ •์˜ํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ ํƒœ๊ทธ์—์„œ ์ž๋™ ์™„์„ฑ ์ง€์›๋ฐ›๊ธฐ
ย