MVVM 패턴의 ViewModel 레이어에 해당하는 화면(View)단 라이브러리
✨Vue의 핵심 - Reactivity
(반응성)
-> 데이터가 바뀌면 변화를 감지하고 알아서 화면에 반영함
인스턴스는 뷰로 화면을 개발하기 위한 생성 단위이다.
Vue를 생성자라고 함 → 필요한 모든 기능을 생성자에 미리 정의해 놓고 사용자가 그 기능을 재정의하여 편리하게 사용하기 때문
인스턴스 생성 방법
new Vue();
인스턴스 속성
new Vue({
el: ,
template: ,
data: ,
methods: ,
created: ,
watch: ,
});
el
: 인스턴스가 그려지는 화면의 시작점 (특정 HTML 태그)template
: 화면에 표시할 요소 ( HTML, CSS 등)data
: 뷰의 반응성(Reactivity)이 반영된 데이터 속성method
: 화면의 동작과 이벤트 로직을 제어하는 메서드created
: 뷰의 라이프 사이틀과 관련된 속성watch
: data에서 정의한 속성이 변화했을 때 추가 동작을 수행할 수 있게 정의하는 속성var vm = new Vue({
// body 태그 안에서#app을 찾아 해당 인스턴스를 붙이겠다는 의미
// el을 정의하지 않으면 속성들을 정의하더라도#app에서 사용할 수 없음
// 즉, 무조건 el을 특정 태그에 붙여줘야만 사용 가능
el : '#app'
});
뷰 인스턴스에서 정의한 속성들을 화면에 표시하는 방법. 콧수염 괄호 {{ }}
<div>{{ message }}</div>
new Vue({
data: {
message: 'Hello World';
}
})
화면 요소를 조작하기 위한 문법.
v-text
→ 자바스크립트 innerText<span v-text="msg"></span>
<!-- 같은 방법 -->
<span>{{msg}}</span>
v-html
→ 자바스크립트 innerHTML<div v-html="html"></div>
v-if
→ 조건부 렌더링v-else
v-else-if
<!-- v-if - loading이 참일 때 보임 -->
<div v-if="loading">Loading...</div>
<!-- v-else - loading이 거짓일 때 보임 -->
<div v-else>test user has been logged in</div>
new Vue({
data: {
loading: false
}
})
v-show
<div v-show="loading">Loading...</div>
new Vue({
data: {
loading: true
}
})
- v-if와 v-show의 차이
v-show를 엘리먼트는 항상 렌더링 되어 DOM에 남아있다. 즉, v-show는 단순히 display 속성(display:none)을 변경하는 것이고, v-if는 조건에 따라 실제로 돔을 제거하고 생성한다.
v-for
<ul>
<li v-for="(item,i) in items">{{ item }}</li>
</ul>
new Vue({
data: {
items: ['Home', 'About', 'Login']
}
})
v-bind
<div v-bind:속성="사용할 속성명(data)"></div>
🍀예시
<!-- id, class 바인딩 -->
<p v-bind:id="uuid" v-bind:class="name">{{number}}</p>
<script>
new Vue({
el: "#app",
data: {
uuid: "abc123",
name: "text-blue",
},
});
</script>
v-on
<button v-on:이벤트 이름="실행할 메소드"></button>
🍀예시
<!-- 클릭할 때마다 이벤트 실행 -->
<button v-on:click="logText">Click Me!</button>
<!-- 키보드를 누를 때마다 이벤트 실행 -->
<input type="text" v-on:keypress="logText" />
<!-- 엔터키를 누를 때마다 이벤트 실행 -->
<input type="text" v-on:keypress.enter="logText" />
<script>
new Vue({
el: "#app",
methods: {
// 이벤트 함수
logText: function () {
console.log("clicked");
},
},
});
</script>
*v-on:이벤트이름.prevent
- 이벤트 새로고침 막기 (event.preventDefault()와 동일)
v-model
<input type="text" v-model="message" />
<p>{{message}}</p>
<script>
new Vue({
el: "#app",
data: {
// input 값이 바뀔 때마다 자동으로 message가 변경됨
message: "",
},
});
</script>
인스턴스 안의 메서드에서 사용되는 this는 해당 인스턴스를 가리킨다.
→ 객체에 속한 메서드에서 사용될 때 this가 해당 메서드를 호출한 객체를 가리키는 것과 비슷한 관점에서 바라보면 됨
간단한 연산 수행 → data가 변경되면 연산 수행
computed 속성은 반응형(reactive) 종속성에 기반하여 캐시된다
<script>
new Vue({
el: "#app",
data: {
number: 100,
},
// number의 값이 바뀌면 doubleNum도 같이 바뀜
computed: {
doubleNum: function () {
return this.number * 2;
},
},
});
</script>
매번 실행되기 부담스러운 무거운 로직 (ex. 데이터 요청)
<script>
new Vue({
el: "#app",
data: {
num: 10,
},
// watch - 데이터의 변화에 따라 특정 로직을 실행
watch: {
num: function () {
this.logText();
},
},
methods: {
addNum: function () {
this.num++;
},
logText: function () {
console.log(`${this.num} changed`);
},
},
});
</script>
*왠만하면 watch보다는 computed를 사용하는걸 추천
컴포넌트는 화면의 영역을 구분하여 개발할 수 있는 뷰의 기능이다.
컴포넌트 기반으로 화면을 개발하게 되면 코드의 재사용성이 올라가고 빠르게 화면을 제작할 수 있다.
컴포넌트는 전역 컴포넌트와 지역 컴포넌트로 구분하여 생성할 수 있다.
전역 컴포넌트
는 인스턴스를 생성할 때마다 따로 등록할 필요 없이 모든 인스턴스에서 사용 가능지역 컴포넌트
는 해당 인스턴스 내에서만 사용 가능, 인스턴스마다 새로 생성해야 함전역 컴포넌트 생성 방법
Vue.component('컴포넌트 이름', {
// 컴포넌트 내용
});
지역 컴포넌트 생성 방법
new Vue({
el: "#app", // #app에서만 사용할 수 있는 지역 컴포넌트
components: {
// '컴포넌트 이름' : { 컴포넌트 내용 },
}
});
🍀예시
// 표시
<div id="app">
<app-header></app-header>
</div>
// 생성
Vue.component("app-header", {
template: "<h1>Header</h1>",
});
상위에서 하위로는 데이터를 내려주고, 하위에서 상위로는 이벤트를 올려준다.
props에도 Reactivity가 반영된다.
props 사용 방식
// 하위 컴포넌트의 내용
var childComponent = {
props: ['프롭스 속성 명']
}
<!-- 상위 컴포넌트의 템플릿 -->
<div id="app">
<child-component v-bind:프롭스 속성 명="상위 컴포넌트의 data 속성"></child-component>
</div>
🍀예시
<div id="app">
<app-header v-bind:propsData="message"></app-header>
</div>
<script>
// 컴포넌트를 분리하여 작성하고 등록하는 방식으로 가독성을 높임
var appHeader = {
template: "<h1>{{ propsData }}</h1>",
props: ["propsData"], // props 속성 이름 지정
};
new Vue({
el: "#app",
components: {
"app-header": appHeader,
}
data: {
message: "hi",
},
});
</script>
// 하위 컴포넌트의 내용
this.$emit('이벤트 명');
<!-- 상위 컴포넌트의 템플릿 -->
<div id="app">
<child-component v-on:하위 컴포넌트에서 발생한 이벤트 명="상위 컴포넌트의 실행할 메서드 이름"></child-component>
</div>
🍀예시
<div id="app">
<app-header v-on:pass="logText"></app-header>
</div>
<script>
var appHeader = {
template: "<button v-on:click='passEvent'>Click Me</button>",
methods: {
passEvent: function () {
this.$emit("pass"); // 이벤트 명
},
},
};
new Vue({
el: "#app",
components: {
"app-header": appHeader,
},
methods: {
// 이벤트 발생시 실행할 메서
logText: function () {
console.log("hi");
},
},
});
</script>
이벤트로 Root로 전달하고 Root에서 props로 전달
var appContent = {
template:
"<div>content<button v-on:click='passNum'>pass</button></div>",
methods: {
passNum: function () {
// 10을 같은 레벨인 appHeader에 전달하기 위해서
// 먼저 Root로 올려 전달하고 Root에서 appHeader로 내려 전달하는 방식
// 상위로 올릴 때는 event 내릴 때는 props
this.$emit("pass", 10);
},
},
};
뷰 라우터는 뷰 라이브러리를 이용하여 SPA를 구현할 때 사용하는 라이브러리이다.
설치 방법
<script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js">
npm install vue-router
라우터 인스턴스 생성
// 라우터 인스턴스 생성
var router = new VueRouter({
// 라우터 옵션
})
// 인스턴스에 라우터 등록
new Vue({
router: router
})
라우터 옵션
routes
: 페이지의 라우팅 정보 (라우팅할 url과 컴포넌트)path
: 페이지의 urlcomponent
: 해당 url에서 표시될 컴포넌트mode
: URL의 해쉬 값(#) 제거 속성url에 따라 해당하는 컴포넌트를 보여주는 태그로 뷰 인스턴스에 라우터를 연결해야 사용 가능하다.
<router-view></router-view>
특정 url로 이동시켜주는 태그로 html a태그와 같은 역할을 한다.
<router-link to="이동할 url"></router-link>
<div id="app">
<div>
<!-- 특정 페이지로 이동시켜줌 -->
<router-link to="/login">Login</router-link>
<router-link to="/home">Home</router-link>
</div>
<!-- url에 따라 해당 하는 컴포넌트를 보여줌 -->
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- CDN vue-router -->
<script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
<script>
var LoginComponent = {
template: "<div>login</div>",
};
var HomeComponent = {
template: "<div>home</div>",
};
new VueRouter({
mode: 'history', // url 해시값 제거
routes: [
// '/login'에서 LoginComponent 컴포넌트 표시
{ path: '/login', component: LoginComponent },
// '/home'에서 HomeComponent 컴포넌트 표시
{ path: '/home', component: HomeComponent }
]
})
new Vue({
// 인스턴스에 라우터 연결
router: router,
});
</script>
CLI (Command Line Interface)
: 명령어를 통해 특정 액션을 실행하는 도구.
프로젝트 생성
vue create '프로젝트 폴더 위치'
프로젝트 실행
npm run serve
파일 구조
<template>
<!-- HTML -->
</template>
<script>
// Javascript - 인스턴스 속성들
</script>
<style>
/* css */
</style>
*템플릿 루트는 무조건 하나여야 한다. -> 전체 태그를 하나의 태그가 감싸고 있어야 함
*파스칼 케이스로 네이밍 + 최소 두단어 이상으로 조합