소프트웨어 기술(스타트업 위주)

vue

vue 정리 입니다. 추가적인 자세한 설명 및 툴 이용 방법은 각 목차별로 공식문서 페이지로 하이퍼링크 참조하겠습니다.


1. create-vue

Vue 3 프로젝트를 시작하는 가장 간단한 방법은 create-vue를 사용하는 것입니다.

설치 및 프로젝트 생성

npm create vue@latest

위 명령어를 실행하면 프로젝트의 설정을 선택하는 프롬프트가 나타납니다.

프로젝트 실행

cd my-vue-app
npm install
npm run dev

이제 브라우저에서 http://localhost:5173 주소로 Vue 애플리케이션을 확인할 수 있습니다.


2. Components

Vue의 컴포넌트 시스템은 재사용 가능한 UI 요소를 만들기 위한 핵심 기능입니다.

2.1 Component Registration

Vue에서는 컴포넌트를 로컬 또는 글로벌로 등록할 수 있습니다.

글로벌 등록

import { createApp } from 'vue'
import App from './App.vue'
import MyComponent from './components/MyComponent.vue'

const app = createApp(App)
app.component('MyComponent', MyComponent)
app.mount('#app')

로컬 등록

<script setup>
import MyComponent from './components/MyComponent.vue'
</script>

<template>
  <MyComponent />
</template>

2.2 Single File Components (SFC)

Vue의 Single File Components (SFC).vue 확장자를 가진 파일로 구성됩니다.

<template>
  <h1>{{ title }}</h1>
</template>

<script setup>
import { ref } from 'vue'
const title = ref('Hello Vue!')
</script>

<style scoped>
h1 {
  color: blue;
}
</style>

2.3 Props

부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 방법입니다.

부모 컴포넌트

<template>
  <ChildComponent message="Hello from Parent!" />
</template>

<script setup>
import ChildComponent from './ChildComponent.vue'
</script>

자식 컴포넌트

<template>
  <p>{{ message }}</p>
</template>

<script setup>
defineProps({ message: String })
</script>

2.4 Events

자식 컴포넌트에서 부모 컴포넌트로 이벤트를 전달하는 방법입니다.

자식 컴포넌트

<template>
  <button @click="$emit('customEvent', 'Hello Parent!')">Click Me</button>
</template>

<script setup>
defineEmits(['customEvent'])
</script>

부모 컴포넌트

<template>
  <ChildComponent @customEvent="handleEvent" />
</template>

<script setup>
import ChildComponent from './ChildComponent.vue'

const handleEvent = (message) => {
  console.log(message)
}
</script>

2.5 V-model

양방향 데이터 바인딩을 위해 사용됩니다.

<template>
  <input v-model="text" />
  <p>{{ text }}</p>
</template>

<script setup>
import { ref } from 'vue'
const text = ref('')
</script>

2.6 Attribute Inheritance

기본적으로 부모 컴포넌트에서 전달된 속성은 자식 컴포넌트의 최상위 요소에 적용됩니다.

<template>
  <ChildComponent class="my-class" />
</template>

<script setup>
import ChildComponent from './ChildComponent.vue'
</script>

자식 컴포넌트

<template>
  <div>Hello World</div>
</template>

위의 코드에서는 class="my-class"가 자동으로 div에 적용됩니다.


3. Templates

Vue 템플릿은 HTML을 기반으로 하고 있으며, Reactivity 시스템과 함께 동작합니다.

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

<script setup>
import { ref } from 'vue'
const message = ref('Hello Vue!')
</script>

4. Directives

4.1 Interpolation

v-text

<p v-text="message"></p>

v-html

<div v-html="htmlContent"></div>

v-bind

<img v-bind:src="imageUrl" />

v-model

<input v-model="inputText" />

v-once

<p v-once>{{ counter }}</p>
<button @click="counter++">Increment</button>

v-pre

<p v-pre>{{ rawText }}</p>

4.2 Conditionals

v-show

<p v-show="isVisible">Visible Text</p>

v-if / v-else / v-else-if

<p v-if="condition">Condition is true</p>
<p v-else-if="anotherCondition">Another condition</p>
<p v-else>Condition is false</p>

4.3 Iterative

v-for

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

4.4 Event Binding

v-on

<button v-on:click="handleClick">Click Me</button>

4.5 Templates

v-slot

<template v-slot:header>
  <h1>Header Content</h1>
</template>

v-cloak

<style>
[v-cloak] {
  display: none;
}
</style>
<p v-cloak>{{ message }}</p>

5. Rendering

5.1 Conditional Rendering

Conditional rendering in Vue allows you to control the display of elements based on certain conditions.

v-if / v-else-if / v-else

v-if removes or adds elements from the DOM based on the condition.

<template>
  <p v-if="user.loggedIn">Welcome, {{ user.name }}!</p>
  <p v-else>Please log in.</p>
</template>

<script setup>
import { ref } from 'vue'

const user = ref({ loggedIn: false, name: 'John' })
</script>

v-show

Unlike v-if, v-show toggles the display CSS property instead of adding/removing elements from the DOM.

<template>
  <p v-show="isVisible">This is always in the DOM but can be hidden.</p>
</template>

<script setup>
import { ref } from 'vue'

const isVisible = ref(true)
</script>

5.2 Rendering Lists

Vue provides the v-for directive for rendering lists dynamically.

<template>
  <ul>
    <li v-for="user in users" :key="user.id">
      {{ user.name }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'

const users = ref([
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' },
])
</script>

5.3 Optimizing Renders

Using key for list rendering

The key attribute helps Vue efficiently update the DOM when modifying lists.

Lazy Loading Components

Using defineAsyncComponent() to dynamically import components improves performance.

<script setup>
import { defineAsyncComponent } from 'vue'

const AsyncComponent = defineAsyncComponent(
  () => import('./HeavyComponent.vue'),
)
</script>

<template>
  <AsyncComponent v-if="showComponent" />
</template>

5.4 Debugging

Vue provides useful debugging tools to inspect and troubleshoot rendering issues.

Using Vue DevTools

Vue DevTools allows you to inspect Vue components, check reactivity, and debug states.

Console Warnings & Errors

Using Vue.config.warnHandler can help log warnings for debugging.

import { createApp } from 'vue'
const app = createApp({})

app.config.warnHandler = (msg, instance, trace) => {
  console.warn(`[Vue Warn]: ${msg}\n${trace}`)
}

6. App Configurations

6.1 Error / Warn Handler

Vue allows you to handle errors and warnings globally.

import { createApp } from 'vue'
const app = createApp({})

app.config.errorHandler = (err, instance, info) => {
  console.error(`[Vue Error]: ${err} in ${info}`)
}

6.2 Global Properties

Global properties allow you to define global variables accessible throughout the app.

app.config.globalProperties.$appName = 'My Vue App'

6.3 Performance

Using Vue’s built-in performance monitoring tools can help optimize app performance.

app.config.performance = true

7. API Styles

7.1 Options API

The Options API is the traditional way of writing Vue components.

<template>
  <p>{{ message }}</p>
</template>

<script>
export default {
  data() {
    return { message: 'Hello from Options API' }
  },
}
</script>

7.2 Composition API

The Composition API provides better reusability and logic organization.

<template>
  <p>{{ message }}</p>
</template>

<script setup>
import { ref } from 'vue'

const message = ref('Hello from Composition API')
</script>

8. LifeCycle Hooks

Vue의 라이프사이클 훅(LifeCycle Hooks)은 Vue 컴포넌트가 생성되고, 업데이트되며, 소멸되는 과정에서 특정 시점에 실행할 수 있는 메서드들입니다.

8.1 라이프사이클 훅 개요

Vue 컴포넌트의 라이프사이클 훅은 다음과 같은 주요 단계로 구성됩니다:

  1. 생성 단계 (Creation Phase)

    • beforeCreate(): 인스턴스가 초기화되기 전 실행됩니다.
    • created(): 인스턴스가 초기화된 후 실행되며, 데이터 반응성이 설정됩니다.
  2. 마운트 단계 (Mounting Phase)

    • beforeMount(): 컴포넌트가 DOM에 마운트되기 직전에 실행됩니다.
    • mounted(): 컴포넌트가 DOM에 마운트된 후 실행됩니다.
  3. 업데이트 단계 (Updating Phase)

    • beforeUpdate(): 데이터가 변경되어 DOM이 업데이트되기 전에 실행됩니다.
    • updated(): 데이터 변경 후 DOM이 업데이트된 후 실행됩니다.
  4. 소멸 단계 (Unmounting Phase)

    • beforeUnmount(): 컴포넌트가 제거되기 전에 실행됩니다.
    • unmounted(): 컴포넌트가 제거된 후 실행됩니다.

8.2 라이프사이클 훅 예제

<script>
export default {
  data() {
    return {
      message: 'Hello Vue!',
    }
  },
  beforeCreate() {
    console.log('beforeCreate - 데이터와 이벤트가 설정되기 전')
  },
  created() {
    console.log('created - 데이터와 이벤트가 설정됨', this.message)
  },
  beforeMount() {
    console.log('beforeMount - 템플릿이 렌더링되기 전')
  },
  mounted() {
    console.log('mounted - 컴포넌트가 마운트됨')
  },
  beforeUpdate() {
    console.log('beforeUpdate - 데이터가 변경되었지만 DOM이 업데이트되기 전')
  },
  updated() {
    console.log('updated - 데이터가 변경되고 DOM이 업데이트됨')
  },
  beforeUnmount() {
    console.log('beforeUnmount - 컴포넌트가 제거되기 전')
  },
  unmounted() {
    console.log('unmounted - 컴포넌트가 제거됨')
  },
}
</script>
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="message = 'Updated Vue!'">Update Message</button>
  </div>
</template>

9. Forms Handling

Vue의 양식(Forms) 처리 기능을 통해 사용자 입력을 효율적으로 관리할 수 있습니다.

9.1 Input Bindings

v-bind를 사용하여 input 요소에 Vue 데이터 속성을 바인딩할 수 있습니다.

<template>
  <div>
    <input :value="message" @input="message = $event.target.value" />
    <p>입력 값: {{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: '',
    }
  },
}
</script>

9.2 v-model

Vue의 v-model 디렉티브를 사용하면 입력 요소와 Vue 데이터 간의 양방향 바인딩을 쉽게 설정할 수 있습니다.

<template>
  <div>
    <input v-model="message" />
    <p>입력 값: {{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: '',
    }
  },
}
</script>

9.3 Modifiers

v-model에는 여러 가지 수정자(Modifiers)가 있으며, 입력 값을 변환하거나 제어할 수 있습니다.

  • .lazy: input 이벤트 대신 change 이벤트에서 동작합니다.
  • .number: 입력 값을 자동으로 숫자로 변환합니다.
  • .trim: 입력값에서 앞뒤 공백을 제거합니다.
<template>
  <div>
    <input v-model.lazy="message" />
    <input v-model.number="age" />
    <input v-model.trim="name" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: '',
      age: 0,
      name: '',
    }
  },
}
</script>

10. Event Handling

Vue에서는 이벤트를 쉽게 바인딩하고 처리할 수 있습니다.

10.1 Binding Events

@event 또는 v-on:event를 사용하여 이벤트를 바인딩할 수 있습니다.

<template>
  <button @click="handleClick">클릭하세요</button>
</template>

<script>
export default {
  methods: {
    handleClick() {
      alert('버튼이 클릭되었습니다!')
    },
  },
}
</script>

10.2 Inline / Method Handlers

이벤트 핸들러를 인라인으로 작성할 수도 있습니다.

<template>
  <button @click="count++">클릭 수: {{ count }}</button>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    }
  },
}
</script>

10.3 Event Modifiers

  • .stop: event.stopPropagation()을 호출하여 이벤트 전파를 중단합니다.
  • .prevent: event.preventDefault()를 호출합니다.
  • .self: 이벤트가 자신에게서 발생했을 때만 실행됩니다.
<template>
  <form @submit.prevent="submitForm">
    <button type="submit">제출</button>
  </form>
</template>

<script>
export default {
  methods: {
    submitForm() {
      alert('폼이 제출되었습니다!')
    },
  },
}
</script>

10.4 Key Modifiers

  • .enter: Enter 키 입력 감지
  • .esc: Escape 키 입력 감지
<template>
  <input @keyup.enter="submit" placeholder="Enter 키를 눌러 제출" />
</template>

<script>
export default {
  methods: {
    submit() {
      alert('Enter 키가 눌렸습니다!')
    },
  },
}
</script>

10.5 Mouse Button Modifiers

  • .left: 마우스 왼쪽 버튼 클릭 감지
  • .right: 마우스 오른쪽 버튼 클릭 감지
<template>
  <button @click.right="handleRightClick">오른쪽 클릭</button>
</template>

<script>
export default {
  methods: {
    handleRightClick() {
      alert('오른쪽 버튼 클릭 감지!')
    },
  },
}
</script>

11. Computed Properties

  • 개요

computed properties는 Vue에서 데이터를 기반으로 새로운 값을 계산하는 데 사용됩니다. 일반적인 methods와 달리, computed properties는 종속된 반응형 데이터가 변경될 때만 다시 평가됩니다. 즉, 캐싱(caching) 기능이 있어 성능 최적화에 유용합니다.

<template>
  <div>
    <p>원본 메시지: {{ message }}</p>
    <p>역순 메시지: {{ reversedMessage }}</p>
    <button @click="message += '!'">메시지 변경</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "Hello Vue!"
    };
  },
  computed: {
    reversedMessage() {
      return this.message.split('').reverse().join('');
    }
  }
};
</script>

12. Routing

  • Vue Router

Vue Router는 Vue.js 애플리케이션에서 클라이언트 측 라우팅을 담당하는 공식 라이브러리입니다. SPA(Single Page Application)에서 URL에 따라 컴포넌트를 동적으로 교체할 수 있도록 도와줍니다.

  • 설치
npm install vue-router
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'

const routes = [
  { path: '/', component: HomeView },
  { path: '/about', component: AboutView },
]

const router = createRouter({
  history: createWebHistory(),
  routes,
})

export default router
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.use(router)
app.mount('#app')
// App.vue
<template>
  <nav>
    <router-link to="/">Home</router-link>
    <router-link to="/about">About</router-link>
  </nav>
  <router-view></router-view>
</template>

13. Forms

  • FormKit

FormKit은 Vue에서 강력한 폼 관리를 제공하는 라이브러리입니다.

  • 설치
npm install @formkit/vue
  • 예제 코드
<template>
  <FormKit type="text" label="이름" v-model="name" />
  <p>입력된 이름: {{ name }}</p>
</template>

<script>
import { createApp } from 'vue';
import { plugin as FormKit } from '@formkit/vue';

export default {
  data() {
    return {
      name: ""
    };
  }
};
</script>

14. SSR

  • Nuxt.js

Nuxt.js는 Vue 기반의 서버 사이드 렌더링(SSR) 프레임워크입니다.

  • 설치
npx nuxi init my-nuxt-app
cd my-nuxt-app
npm install
  • 예제 코드
// pages/index.vue
<template>
  <div>
    <h1>Nuxt.js SSR Example</h1>
    <p>서버에서 렌더링된 페이지입니다.</p>
  </div>
</template>

15. SSG

  • VitePress

VitePress는 Vue 기반의 정적 사이트 생성기(SSG)입니다.

  • 설치
npm create vitepress@latest my-docs
cd my-docs
npm install
  • 예제 코드
# Hello VitePress

VitePress로 정적 웹사이트를 쉽게 만들 수 있습니다.

16. State Management

  • Pinia

Pinia는 Vue의 공식 상태 관리 라이브러리입니다.

  • 설치
npm install pinia
  • 예제 코드
// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: {
    increment() {
      this.count++
    },
  },
})
// 사용 예제
<template>
  <p>Count: {{ counter.count }}</p>
  <button @click="counter.increment">증가</button>
</template>

<script>
import { useCounterStore } from './stores/counter';

export default {
  setup() {
    const counter = useCounterStore();
    return { counter };
  }
};
</script>
Previous
next