Vue ์‹œ์ž‘ํ•˜๊ธฐ + ๋ฏธ๋ฆฌ๋ณด๊ธฐ

Select
Nov 20, 2023
  • ํ˜„์žฌ Vue๋Š” 2๋ฒ„์ „์—์„œ 3๋กœ ์ด๋™์ค‘ .. โ†’ ์•ž์œผ๋กœ Vue3๋กœ ์ง„ํ–‰ํ•  ์˜ˆ์ •
 
  • ๋ฐ์ดํ„ฐ์™€ DOM์ด ์—ฐ๊ฒฐ๋จ โ†’ ๋ฐ˜์‘ํ˜•(๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ํ™”๋ฉด์ด ๋ฐ”๋€๋‹ค)
 
  • ์ตœ์‹  ๋ฒ„์ „ ์‹œ์ž‘ ํ•˜๊ธฐ - CDN ๋ฐฉ๋ฒ•
    • index.html์—์„œ head์— <script src=โ€https://unpkg.com/vue@nextโ€></script> ์ฝ”๋“œ ์ถ”๊ฐ€
    • CDN ๋ฐฉ๋ฒ•์€ ์ „์—ญ Vue ๊ฐœ์ฒด๋ฅผ ํ†ตํ•ด ์ „์—ญ API์˜ ํ•จ์ˆ˜(ex. createApp)์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค
  • Vue.createApp(์˜ต์…˜).mount(ํƒ€๊ฒŸ์…€๋ ‰ํ„ฐ)
    • vue ๋ฐฉ์‹์œผ๋กœ ํƒ€๊ฒŸ ์…€๋ ‰ํ„ฐ์— ๋ Œ๋”๋ง ์‹œํ‚ค๊ณ , ์ปดํฌ๋„ŒํŠธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜
    • ์˜ต์…˜ ๊ฐ์ฒด์— data๋ฉ”์„œ๋“œ, mouted๋ฉ”์„œ๋“œ, methods ์†์„ฑ, components ์†์„ฑ ๋“ฑ์ด ์˜ฌ ์ˆ˜ ์žˆ๋‹ค
    • ์ƒ์„ฑ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ธ์Šคํ„ด์Šค์—์„œ data๋ฅผ ์†์„ฑ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค(ex. vm.counter)
  • data ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฆฌํ„ดํ•˜๋Š” ๊ฐ์ฒด ๋ฉค๋ฒ„๋กœ ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค
  • mounted ํ›…์œผ๋กœ ๋งˆ์šดํŠธ ๋  ๋•Œ(๋ Œ๋”๋ง ๋  ๋•Œ) ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๋กœ์ง์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค(์ธ์Šคํ„ด์Šค ๋ฐ˜ํ™˜)
  • vue.js์—์„œ ์„ ์–ธํ•œ ๋ณ€์ˆ˜ ๋“ฑ์„ html์—์„œ ์ด์ค‘ ์ค‘๊ด„ํ˜ธ({{ }}) ์•ˆ์—์„œ ์‚ฌ์šฉํ•ด์„œ ๋ณด๊ฐ„ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋‹ค
... <script src="https://unpkg.com/vue@next"></script> //vue ์‹œ์ž‘ํ•˜๊ธฐ </head> <body> <div id="app"> {{counter}} //vue์—์„œ ์„ ์–ธ๋œ data ์‚ฌ์šฉํ•˜๊ธฐ </div> <script> const app = { //์ปดํฌ๋„ŒํŠธ data() { //๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ return { //๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ counter:0 } }, mounted() { //mount๋˜๋ฉด ์‹คํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ(์„ ํƒ) setInterval(()=> { this.counter += 1 //ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—ฌ์•ผ ํ•จ -> this๋Š” ๋ณ€์ˆ˜ app์„ ๊ฐ€๋ฆฌํ‚ด }, 1000) } } const vm = Vue.createApp(app) //vue ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒ์„ฑ .mount('#app') //html ์š”์†Œ์— ์—ฐ๊ฒฐํ•˜๊ธฐ(์ฒด์ด๋‹ ๋ฐฉ์‹) => ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ </script> </body>
 

๋””๋ ‰ํ‹ฐ๋ธŒ (v-)

  • ์…€๋ ‰ํ„ฐ ์†์„ฑ์— v-bind: ๋ฅผ ๋ถ™์—ฌ์„œ ๊ฐ’์„ ๋ฐ์ดํ„ฐ๋กœ ์ทจ๊ธ‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๋ถ™์œผ๋ฉด ๊ฐ’์€ js๋กœ ์ฝํž ์ˆ˜ ์žˆ๋‹ค
    • vue์˜ data ๋ฉ”์„œ๋“œ์— ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋ฅผ ์ค‘๊ด„ํ˜ธ ๋‘๋ฒˆ ํ•„์š” ์—†์ด ๋ฐ”๋กœ ์“ธ ์ˆ˜ ์žˆ์Œ
    • ex) v-bind:class=โ€{ ํด๋ž˜์Šค๋ช…: true }โ€์ด๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค๋ช…์ด ์ ์šฉ ๋œ๋‹ค
      • ex2) v-bind:fruit-name=โ€nameโ€
  • ์…€๋ ‰ํ„ฐ ์†์„ฑ์— v-on:์œผ๋กœ method ์—ญ์‹œ ๋ถ™์ผ ์ˆ˜ ์žˆ๋‹ค
    • ์•ž์„œ, vue.js์—์„œ methods๋ผ๋Š” ์†์„ฑ์œผ๋กœ ๋ฉ”์„œ๋“œ๋“ค์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค
    • ์ด๋ ‡๊ฒŒ ์„ ์–ธํ•œ ๋ฉ”์„œ๋“œ๋“ค์€ v-on:์ž์Šค์ด๋ฒคํŠธ์ด๋ฆ„=โ€๋ฉ”์„œ๋“œ์ด๋ฆ„โ€ ๋“ฑ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
      • ex) v-on:click, v-on:scroll, v-on:dragstart
      <body> <style> .orange{ //orange ํด๋ž˜์Šค์— ์Šคํƒ€์ผ ์ ์šฉ color: orange } </style> <div id="app"> <div v-bind:class="{ orange: active }">{{counter}}</div> //active ๊ฐ’์— ๋”ฐ๋ผ orange ํด๋ž˜์Šค๋ช…์ด ์ถ”๊ฐ€ <button v-on:click="increase">Click me!</button> //button์˜ click ํ•จ์ˆ˜ ๊ฐ’์œผ๋กœ increase ๋ฉ”์„œ๋“œ </div> <script> const app = { data() { return { counter: 0, active: true //data์— ๋ฆฌํ„ด ๊ฐ’์— active ์†์„ฑ ์ถ”๊ฐ€ } }, methods: { //methods๋ผ๋Š” ์†์„ฑ์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธ ๊ฐ€๋Šฅ increase() { //counter๋ฅผ 1 ์ฆ๊ฐ€ํ•˜๋Š” ๋ฉ”์„œ๋“œ this.counter += 1 } } } const vm = Vue.createApp(app).mount('#app') </script> </body>
 
  • v-if="๊ฐ’" โ‡’ ๊ฐ’์ด true์ด๋ฉด ํ•ด๋‹น ์…€๋ ‰ํ„ฐ ์š”์†Œ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค
    • <div id="app"> <div v-if="active">์งœ์ž”</div> //๋””๋ ‰ํ‹ฐ๋ธŒ <button v-on:click="toggle">Click me!</button> </div> <script> const app = { data() { return { active: true } }, methods: { toggle() { this.active = !this.active } } } const vm = Vue.createApp(app).mount('#app') </script>
 
  • v-for=โ€์š”์†Œ in ๋ฐฐ์—ด๋“ฑโ€ ํ˜•ํƒœ๋กœ ๋ฐฐ์—ด ๋“ฑ์„ ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฆฐ ํ›„์—, ํ•ด๋‹น ํƒœ๊ทธ์˜ ์ž์‹์—์„œ๋Š” {{์š”์†Œ}}๋กœ, ์ž์‹ ์†์„ฑ ๋“ฑ์˜ ๊ฐ’์œผ๋กœ๋Š” โ€œ์š”์†Œโ€ ์š”์†Œ๋ฅผ ์“ธ ์ˆ˜ ์žˆ๋‹ค
    • ๋ฐฐ์—ด์—๋Š” script์—์„œ data๋กœ ์„ ์–ธํ•œ ๊ฒƒ์ด ์˜ค๊ณ , ์š”์†Œ์˜ ์ด๋ฆ„์€ ์•„๋ฌด๊ฑฐ๋‚˜ ์˜ฌ ์ˆ˜ ์žˆ๋‹ค
    • <div id="app"> <ul v-for="fruit in fruits"> <li> {{fruit}} </li> </ul> </div> <script> const app = { data() { return { fruits: ['apple', 'banana', 'kiwi'] } } } const vm = Vue.createApp(app).mount('#app') </script>
  • v-model ๋””๋ ‰ํ‹ฐ๋ธŒ : ์–‘์‹์— ๋Œ€ํ•œ ์ž…๋ ฅ๊ณผ ์•ฑ ์ƒํƒœ๋ฅผ ์–‘๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ”์ธ๋”ฉ
    • ex) input ์š”์†Œ์˜ ๊ฐ’์œผ๋กœ ๋ณ€์ˆ˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์—ˆ์„ ๋•Œ, ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด input ์š”์†Œ์˜ ๊ฐ’์ด ๊ฐ™์ด ์ˆ˜์ •๋˜๊ณ  ์—ญ์œผ๋กœ๋„ ์˜ํ–ฅ์„ ๋ผ์นจ
 

์ปดํฌ๋„ŒํŠธ

  • App์˜ ๊ฐ์ฒด ๋ฉค๋ฒ„๋กœ components๋ฅผ ๋‘˜ ์ˆ˜ ์žˆ๊ณ , ๊ฐ’์„ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ›๊ณ  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฉค๋ฒ„๋กœ ๋‘”๋‹ค
    • ์ปดํฌ๋„ŒํŠธ ๊ฐ์ฒด: ๋ฉค๋ฒ„ template์—์„œ renderํ•˜๊ณ  ์‹ถ์€ html์ฝ”๋“œ, ๋ฉค๋ฒ„ props์—์„œ ์ „๋‹ฌ๋ฐ›์€ props
  • script์—์„œ ์„ ์–ธ๋œ components๋ฅผ ๊บฝ์‡ ๋กœ html ์ฝ”๋“œ์—์„œ ์“ธ ์ˆ˜ ์žˆ๋‹ค
    • ์ฃผ์˜) js์—์„œ๋Š” components์™€ props ์ด๋ฆ„์„ ์นด๋ฉœ ์ผ€์ด์Šค๋กœ, html์—์„œ๋Š” ๋Œ€์‹œ ์ผ€์ด์Šค๋กœ ๋ฐ›์Œ. (๋ทฐ๊ฐ€ ์•Œ์•„์„œ ๋ณ€ํ™˜ํ•˜์—ฌ ๋งค์นญ ํ•ด์คŒ)
<div id="app"> <ul v-for="name in fruits"> <fruit-item v-bind:fruit-name="name"></fruit-item> </ul> </div> <script> const FruitItem = { props: ['fruitName'], template: "<li>{{fruitName}}</li>" } const app = { components: { FruitItem }, data() { return { fruits: ['apple', 'banana', 'kiwi'] } } } const vm = Vue.createApp(app).mount('#app') </script>
 

 
  • live server ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ๋ฐ”๋กœ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.(์ €์žฅ ์‹œ ์ž๋™ ์ƒˆ๋กœ๊ณ ์นจ)
    • ์ฝ”๋“œ ์šฐํด๋ฆญ ํ›„ Open with live server ํด๋ฆญ
  • script์˜ ์ „์—ญ ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์„ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์ฝ˜์†”์— ์ž…๋ ฅํ•˜๋ฉด, ํ•ด๋‹น ๋ณ€์ˆ˜ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค
    • notion image
    • counter๋Š” app.counter๋กœ ์ ‘๊ทผ, ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค
  • ํ•จ์ˆ˜์— ๋”ฐ๋ฅธ this
    • ์ผ๋ฐ˜ function ํ•จ์ˆ˜ โ‡’ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์œ„์น˜์—์„œ ์ •์˜
    • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ โ‡’ ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋˜๋Š” ์œ„์น˜์—์„œ ์ •์˜
      • ๋ณดํ†ต์€ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์จ์„œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ