소프트웨어 기술(스타트업 위주)
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 컴포넌트의 라이프사이클 훅은 다음과 같은 주요 단계로 구성됩니다:
생성 단계 (Creation Phase)
beforeCreate()
: 인스턴스가 초기화되기 전 실행됩니다.created()
: 인스턴스가 초기화된 후 실행되며, 데이터 반응성이 설정됩니다.
마운트 단계 (Mounting Phase)
beforeMount()
: 컴포넌트가 DOM에 마운트되기 직전에 실행됩니다.mounted()
: 컴포넌트가 DOM에 마운트된 후 실행됩니다.
업데이트 단계 (Updating Phase)
beforeUpdate()
: 데이터가 변경되어 DOM이 업데이트되기 전에 실행됩니다.updated()
: 데이터 변경 후 DOM이 업데이트된 후 실행됩니다.
소멸 단계 (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>