Vue CLI 설치
$ npm install -g @vue/cli
# or
$ yarn global add @vue/cli
# or
$ yarn dlx @vue/clie
$ vue --version # 확인
$ npm list -g --depth=0 # npm 설치 리스트 확인
</shx>
- Vue CLI 삭제 <sxh bash>
$ npm uninstall -g vue-cli
vue 프로젝트 생성
$ vue create <프로젝트 이름>
$ cd <프로젝트 이름>
$ npm run serve
vuetify 패키지 추가
$ vue add vuetify
vue-router 설치
$ vue add router
</bash>
- vuex 설치 <sxh bash>
$ vue add vuex
-
CDN 이용
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- production version, optimized for size and speed -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
Vue.js 기본 구조
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title>Vue.js App</title>
<link href="main.css" rel="stylesheet">
</head>
<body>
<div id="app">
<!-- template 출력 -->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>
var app = new Vue({
el: '#app'
})
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
var app = new Vue({
// el
el: '#app',
// data
data: {
message: 'Vue.js'
},
// computed
computed: {
computedMessage: function() {
return this.message + '!'
}
},
// lifecycle hooks
created: function() {
// something to what you do
},
// methods
methods: {
myMethod: function() {
// something to what you do
}
}
})
Lifecycles |
Methods | Timing |
beforeCreate | 인스턴스가 생성되고, 리액티브 초기화가 일어나기 전 |
created | 인스턴스가 생성되고, 리액티브 초기화가 일어난 후 |
beforeMount | 인스턴스가 마운트되기 전 |
mounted | 인스턴스가 마운트된 후 |
beforeUpdate | 데이터가 변경되어 DOM에 적용되기 전 |
updated | 데이터가 변경되어 DOM에 적용된 후 |
beforeDestroy | Vue 인스턴스가 제거되기 전 |
destroyed | Vue 인스턴스가 제거된 후 |
errorCaptured | 임의의 자식 컴포넌트에서 오류가 발생했을 때 |
v-bind 장식자 |
장식자 | 의미 |
.prop | 속성 대신에 DOM 속성으로 바인딩, DOM 속성과 직접 바인딩 |
.camel | 케밥케이스1) 속성 이름을 카멜 케이스로 변환 |
.sync | 양방 바인딩 |
템플렛 제어 디렉티브 |
디렉티브 | 설명 |
v-pre | 템플릿 컴파일 생략 |
v-once | 한 번만 바인딩 |
v-text | Mustache 대신 텍스트 콘텐츠로 렌더링 |
v-html | HTML 태그를 그대로 렌더링 |
v-cloak | 인스턴스 준비가 끝나면 제거 |
Event Handling
이벤트 장식자 |
장식자 | 설명 |
.stop | event.stopPropagation()을 호출 |
.prevent | event.preventDefault()를 호출 |
.capture | 캡처 모드로 DOM 이벤트를 핸들 |
.self | 이벤트가 해당 요소에서 직접 발생할 때만 핸들러를 호출 |
.native | 컴포넌트의 루트 요소 위에 있는 네이티브 이벤트를 핸들 |
.once | 한 번만 핸들 |
.passive | {passive: true}로 DOM 이벤트를 핸들 |
클릭 이벤트 |
장식자 | 설명 |
.left | 마우스 왼쪽 버튼으로 눌렀을 때만 핸들러 호출 |
.right | 마우스 오른쪽 버튼으로 눌렀을 때만 핸들러 호출 |
.middle | 마우스 중간 버튼으로 눌렀을 때만 핸들러 호출 |
키 코드 별칭 |
별칭 | 의미 |
.enter | Enter(엔터) 키를 눌렀을 때 |
.tab | Tab(탭) 키를 눌렀을 때 |
.delete | Delete(딜리트) 키를 눌렀을 때 |
.esc | ESC 키를 눌렀을 때 |
.space | Space(스페이스) 키를 눌렀을 때 |
.up | 화살표 위 키를 눌렀을 때 |
.down | 화살표 아래 키를 눌렀을 때 |
.left | 화살표 왼쪽 키를 눌렀을 때 |
.right | 화살표 오른쪽 키를 눌렀을 때 |
시스템 장식자 |
별칭 | 의미 |
.ctrl | Ctrl(컨트롤) 키가 눌린 경우 |
.alt | Alt(안트) 키가 눌린 경우 |
.shift | Shift(시프트) 키가 눌린 경우 |
.meta | Meta(메타) 키가 눌린 경우 |
v-model 장식자 |
장식자 | 의미 |
.lazy | input 대신 change 이벤트 핸들링 |
.number | 값을 숫자로 변환 |
.trim | 값 양쪽에 있는 쓸데없는 공백 제거 |
new Vue({
// ..
watch: {
<감시할 데이터>: function(<새로운 값>, <이전 값>) {
// value가 변화했을 때 하고 싶은 처리
},
'item.value': function(newVal, oldVal) {
// 객체의 속성도 감시할 수 있음
},
list: {
handler: function(newVal, oldVal) {
// list가 변경될 때 하고 싶은 처리
},
deep: true, // 속성: deep, 값: Boolean, 네스트된 객체도 감시할지
immediate: true // 속성: immediate, 값: Boolean, 처음 값을 읽어 들이는 시점에도 호출할지
}
}
})
사용자 정의 디렉티브에서 사용할 수 있는 훅 |
메서드 이름 | 시점 |
bind | 디렉티브가 처음 요소와 연결될 때 |
inserted | 연결된 요소가 부모 Node에 삽입될 때 |
update | 연결된 요소를 내포하고 있는 컴포넌트의 VNode가 변경되었을 때 |
componetUpdated | 내포하고 있는 컴포넌트와 자식 컴포넌트의 VNode가 변경되었을 때 |
unbind | 연결되어 있는 요소로부터 디렉티브가 제거될 때 |
훅 매개변수 |
매개변수 | 내용 |
el | 디렉티브가 연결되어 있는 요소 |
binding | 배인드된 값, 매개변수, 장식자가 들어 있는 객체 |
vnode | 요소에 대응되는 VNode |
oldVnode | 변경 이전의 VNode(update 또는 componentUpdated에서만 사용 가능) |
binding의 속성 |
속성 | 설명 |
arg | 매개변수 |
modifiers | 장식자 객체 |
value | 새로운 값 |
oldValue | 이전 값(update 또는 componentUpdated에서만 사용 가능) |
트랜지션 클래스의 시점 |
Enter 계열의 클래스 | 대상 요소가 DOM에서 삽입될 때의 트랜지션 페이즈 |
.v-enter | 대상 요소가 DOM에 삽입되기 전에 추가되며, 트랜지션이 종료될 때 사라짐. Enter 액티브 상태 |
.v-enter-to | 트랜지션이 실제로 시작될 때 추가되며, 트랜지션이 종료될 때 사라짐. Enter의 종료 완료 |
.v-enter-active | 대상 요소가 DOM에 삽입되기 전에 추가되며, 트랜지션이 종료될 때 사라짐. Enter의 액티브 상태 |
Leave 계열의 클래스 | 대상 요소가 DOM에서 제거될 때의 트랜지션 페이즈 |
.v-leave | 트랜지션 시작 전에 추가되며, 트랜지션 개시 때는 사라짐. Leave 시작 상태 |
.v-leave-to | 트랜지션 시작 전에 추가되어, 트랜지션이 종료되었을 때 사라짐. Leave 종료 상태 |
.v-leave-active | 트랜지션 시작 전에 추가되어, 트랜지션이 종료되었을 때 사라짐. Leave의 액티브 상태 |
Enter와 Leave 시점 변경 |
모드 | 동작 |
in-out | Enter 트랜지션이 종료되고 나서 Leave 트랜지션 시작 |
out-in | Leave 트랜지션이 종료되고 나서 Enter 트랜지션 시작 |
사용할 수 있는 트랜지션 훅 |
Enter 계열 훅 | 시점 |
before-enter | DOM에 요소가 추가되기 전 |
enter | .v-enter가 있는 DOM에 요소가 추가된 후 |
after-enter | 트랜지션이 끝나거나 또는 enter에서 done()을 호출한 후 |
enter-cancelled | enter 페이즈가 중간에 취소되었을 때 |
Leave 계열 훅 | 시점 |
before-leave | 클래스가 추가되기 전 |
leave | .v-leave가 추가된 후 |
after-leave | DOM에서 요소가 제거된 후 또는 leave에서 done()을 호출한 후 |
leave-cancelled | leave 페이즈가 중간에 취소되었을 때 |
npm install –save vue@2.6.14
npm 기본 명령어 |
명령어 | 생략 기법 | 설명 |
npm install –global | npm i -g | 전역 위치에 설치 |
npm install –save | npm i -s | 프로젝트 결과물을 동작시키기 위해서 필요한 패키지를 설치 |
npm install –save-dev | npm i -D | 개발 중에만 필요한 패키지 설치 |
$ npm install -g vue-cli
$ vue --version
# 프로젝트 생성 명령어의 기본 형태
$ vue init <템플릿 이름> <프로젝트 이름>
$ cd <프로젝트 이름>
$ npm install
$ vue init webpack my-app
$ npm run dev
$ npm run build
// Vue와 Vuex 모듈 읽어 들이기
import Vue from 'vue'
import Vuex from 'vuex'
// Vue에 Vuex 등록하기
Vue.use(Vuex)
# 최신 버전 설치
$ npm install vuex babel-polyfill
# 버전 지정
$ npm install vuex@3.1.0 babel-polyfill@6.26.
import 'babel-polyfill'
import Vue from 'vue'
import Vuex from 'vuex'
// 플러그인으로 등록
Vue.use(Vuex)
// 스토어 만들기
const store = new Vuex.store({
state: {
count: 0
},
mutations: {
// 카운트 업하는 뮤테이션 등록, 매개변수로 전달
increment(state) {
state.count++
}
// increment: state => { state.count++ } // 위와 같은 동작을 하는 코드
}
})
export default store
import store from '@/store.js' // @는 디폴트로 등록되어 있는 src 디렉토리의 별칭
console.log(store.state.count) // -> 0
// 스토어의 상태 변경
// increment 커밋
store.commit('increment')
// 값이 변경된 것을 확인
console.log(store.state.count) // -> 1
import store from './store.js'
new Vue({
el: '#app',
store, // store 등록
render: h => h(App)
})
export default {
created() {
// 스토어의 상태 확인
console.log(this.$store.state.count)
// 스토어의 상태 변경
this.$store.commit('increment')
}
}
Vue Router 설치
$ npm install vue-router
$ npm install vue-router@3.0.6
import Vue from 'vue'
import VueRouter from 'vue-router'
// 플러그인으로 등록
Vue.use(VueRouter)
Vue Router 내장 컴포넌트 |
사용자 정의 태그 | 설명 |
<router-view> | 라우트와 일치하는 컴포넌트를 렌더링 |
<router-link> | 라우트 링크를 생성 |
import Vue from 'vue'
import VueRouter from 'vue-router'
// 라우트 전용 컴포넌트 읽어 들이기
import Home from '@/views/Home.vue'
import Product from '@/views/Product.vue'
// Vuex와 마찬가지로 플러그인 등록
Vue.use(VueRouter)
// VueRouter 인스턴스 생성
const router = new VueRouter({
// URL의 경로와 연결할 컴포넌트 맵핑하기
routes: [
{ path: '/', component: Home },
{ path: '/product', component: Product }
]
})
// 생성한 VueRouter 인스턴스 익스포트
export default router
import router from './router.js'
new Vue({
el: '#app',
router, // 애플리케이션 등록
render: h => h(App)
})
<template>
<div id="app">
<nav>
<router-link to="/">Home</router-link>
<router-link to="/product">상품 정보</router-link>
</nav>
<!-- 여기에 경로에 일치하는 컴포넌트가 들어감 -->
<router-view />
</div>
</template>
객체 형식으로 지정 |
객체 | 설명 |
name | 라우트 이름 |
path | 라우트 경로 |
params | 요청 매개변수 객체 |
query | 쿼리 객체 |
액티브 링크 하이라이트 |
클래스 | 설명 |
.router-link-exact-active | 전체가 매치되는 라우트 |
.router-link-active | 매치한 경로를 포함하는 라우트 |
프로그램으로 내비게이션 |
메서드 | 설명 |
push | 이력 엔트리 추가 |
replace | 이력 엔트리 수정 |
go | 브라우저 레벨에서 페이지 이동 |
내비게이션 가드의 매개변수 |
매개 변수 | 설명 |
to | 이동 후의 라우트 객체 |
from | 이동 전의 라우트 객체 |
next | 내비게이션 해결 전용 콜백 함수 |
라우트 단위 가드 |
메서드 이름 | 시점 |
beforeEnter | 라우트 이동 전 |
전역 가드 |
메서드 이름 | 시점 |
beforeEach | 모든 라우트의 이동 전, 컴포넌트 가드 해결 전 |
beforeResolve | 모든 라우트의 이동 전, 컴포넌트 가드 해결 후 |
afterEach | 모든 라우트의 이동 후 |
컴포넌트 가드 |
메서드 이름 | 시점 |
beforeRoutEnter | 해당 컴포넌트로 이동하기 전 |
beforeRouteUpdate | 해당 컴포넌트에서 라우트가 변경되기 전 |
beforeRouteLeave | 해당 컴포넌트에서 밖으로 이동하기 전 |
Parent는 v-bind, Child는 props를 이용
<template>
<div> 하위 컴포넌트에 데이터 값을 알려줍니다.
<ChildComponent v-bind:childVaule="parentVaule" />
</div>
</template>
<script>
import ChildComponent from "@/components/childComponent.vue";
export default {
name: "ParentComponent",
components: { ChildComponent },
data: function () {
return {
parentVaule: 20,
};
},
};
</script>
<template>
<div>{{ this.childVaule }} : 상위 컴포넌트로부터 받아온 값</div>
</template>
<script>
export default {
name: "ChildComponent",
props: ["childVaule"], };
</script>
Child에서 $emit, Parent에서 v-on을 이용
<template>
<button @click="updateParentValue">클릭시 부모의 데이터 값이 증가합니다.</button>
</template>
<script>
export default {
name: "ChildComponent",
methods: {
updateParentValue() {
this.$emit("childEvent");
},
},
};
</script>
<template>
<div>
<ChildComponent v-on:childEvent="updateParentValue" />
</div>
</template>
<script>
import ChildComponent from "@/components/childComponent.vue";
export default {
name: "ParentComponent",
components: { ChildComponent },
data: function () {
return {
parentVaule: 20,
};
},
methods: {
updateParentValue() {
this.parentVaule++;
console.log(this.parentVaule) // 21, 22, 22, 누를때마다 증가하는 것 확인 가능
},
},
};
</script>