Syw.Frontend

๐Ÿงฉ Vue 2๋กœ ๋ฐฐ์šฐ๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ธฐ์ดˆ

1๋‹จ๊ณ„. Vue 2 + Express + Axios ์ธ์ฆ ๊ธฐ๋ฐ˜ ํˆฌ๋‘์•ฑ ๋งŒ๋“ค๊ธฐ

1-2. Vue ์ธ์Šคํ„ด์Šค์™€ ํ…œํ”Œ๋ฆฟ ๋ฌธ๋ฒ• ์ดํ•ดํ•˜๊ธฐ

๐ŸŽฏ ํ•™์Šต ๋ชฉํ‘œ

  • Vue ์ธ์Šคํ„ด์Šค์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๊ณ  ์ง์ ‘ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ…œํ”Œ๋ฆฟ ๋ฌธ๋ฒ•์„ ํ†ตํ•ด ํ™”๋ฉด์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ๋™์ ์œผ๋กœ ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ๋‹ค.

1๏ธโƒฃ Vue ์ธ์Šคํ„ด์Šค๋ž€?

Vue ์•ฑ์€ new Vue()๋กœ ์‹œ์ž‘ํ•˜๋Š” Vue ์ธ์Šคํ„ด์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

Vue 2์—์„œ๋Š” ์ด ์ธ์Šคํ„ด์Šค๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์„ ์–ธํ•˜๊ณ , DOM๊ณผ ์—ฐ๊ฒฐ(binding)ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”ง main.js ์˜ˆ์‹œ

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

render: h => h(App)๋Š” ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ(App.vue)๋ฅผ DOM์— ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.


2๏ธโƒฃ ํ…œํ”Œ๋ฆฟ ๋ฌธ๋ฒ• ๊ธฐ๋ณธ

โœ… ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ (Interpolation)

<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: '์•ˆ๋…•ํ•˜์„ธ์š”, Vue!'
    }
  }
}
</script>

โœ… ์†์„ฑ ๋ฐ”์ธ๋”ฉ: v-bind

<img v-bind:src="imageUrl" alt="์ด๋ฏธ์ง€" />

์ถ•์•ฝํ˜•: :src="imageUrl"


3๏ธโƒฃ ๋””๋ ‰ํ‹ฐ๋ธŒ(Directive)

โœ… ์กฐ๊ฑด ๋ Œ๋”๋ง: v-if, v-else, v-show

<p v-if="isLoggedIn">ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค!</p>
<p v-else>๋กœ๊ทธ์ธ ํ•ด์ฃผ์„ธ์š”.</p>

โœ… ๋ฐ˜๋ณต ๋ Œ๋”๋ง: v-for

<ul>
  <li v-for="(item, index) in items" :key="index">
    {{ index + 1 }}. {{ item }}
  </li>
</ul>

<script>
export default {
  data() {
    return {
      items: ['HTML', 'CSS', 'Vue']
    }
  }
}
</script>

4๏ธโƒฃ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง: v-on

<button v-on:click="handleClick">ํด๋ฆญ</button>

์ถ•์•ฝํ˜•: @click="handleClick"

methods: {
  handleClick() {
    alert('๋ฒ„ํŠผ์ด ํด๋ฆญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!')
  }
}

๐Ÿ’ป ์‹ค์Šต: ๊ฐ„๋‹จํ•œ ํ•  ์ผ ๋ฆฌ์ŠคํŠธ

<template>
  <div class="todo-container">
    <h2>๐Ÿ“ ์˜ค๋Š˜์˜ ํ•  ์ผ</h2>
    <div class="form">
      <input v-model="newTodo" placeholder="ํ•  ์ผ์„ ์ž…๋ ฅํ•˜์„ธ์š”" />
      <button @click="addTodo">์ถ”๊ฐ€</button>
    </div>
    <ul class="todo-list">
      <li v-for="(todo, i) in todos" :key="i">
        โœ… {{ todo }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      newTodo: '',
      todos: []
    }
  },
  methods: {
    addTodo() {
      if (this.newTodo.trim()) {
        this.todos.push(this.newTodo.trim())
        this.newTodo = ''
      }
    }
  }
}
</script>

<style scoped>
.todo-container {
  max-width: 400px;
  margin: 40px auto;
  padding: 24px;
  border: 1px solid #ccc;
  border-radius: 12px;
  background: #f9f9f9;
  box-shadow: 0 4px 10px rgba(0,0,0,0.05);
}

.todo-container h2 {
  text-align: center;
  margin-bottom: 20px;
}

.form {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}

.form input {
  flex: 1;
  padding: 8px;
  border: 1px solid #aaa;
  border-radius: 6px;
  font-size: 14px;
}

.form button {
  padding: 8px 16px;
  background-color: #42b983;
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
}

.form button:hover {
  background-color: #36956d;
}

.todo-list {
  list-style: none;
  padding: 0;
}

.todo-list li {
  padding: 6px 0;
  font-size: 16px;
  border-bottom: 1px dashed #ddd;
}
</style>

โœ… ๋งˆ๋ฌด๋ฆฌ ์ •๋ฆฌ

  • Vue ์ธ์Šคํ„ด์Šค๋Š” ์•ฑ์˜ ๋ฟŒ๋ฆฌ์ด๋ฉฐ, data, methods ๋“ฑ์˜ ์˜ต์…˜์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
  • ํ…œํ”Œ๋ฆฟ ๋ฌธ๋ฒ•์€ ๋ฐ์ดํ„ฐ๋ฅผ ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๊ฑฐ๋‚˜ ์กฐ๊ฑด, ๋ฐ˜๋ณต, ์ด๋ฒคํŠธ๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.
  • v-model์„ ์ด์šฉํ•ด ์–‘๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ๋„ ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ’ฌ ๋Œ“๊ธ€

    โ€ป ๋กœ๊ทธ์ธ ํ›„ ๋Œ“๊ธ€์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.