Vue는 사용자 인터페이스를 만들기 위한 프로그레시브 프레임워크이다.
모든 Vue 어플리케이션은 createApp
함수를 사용하여 새로운 어플리케이션 인스턴스를 생성하여 시작한다.
const app = Vue.createApp()
인스턴스가 생성되면, mount
메소드에 컨테이너를 전달하여 mount 할 수 있다.
어플리케이션 인스턴스에 노출되니 대부분의 메소드들은 동일한 인스턴스를 반환하여 연결(chaning)을 허용한다
const RootComponent = {}
const app = Vue.createApp(RootComponent)
const vm = app.mount('#app')
최상위 컴포넌트는 어플리케이션을 mount할 때(하나의 프로젝트를 시작할 때), 렌더링의 시작점으로 사용된다.
각 컴포넌트는 생성될 때 일련의 초기화 단계를 거친다. 예를 들어 데이터 관찰, 템플릿 컴파일, 인스턴스를 DOM에 마운트, 데이터 변경 시 DOM을 업데이트 해야한다.
그 과정에서 라이프사이클 훅이라 불리우는 함수도 실행하여 사용자가 특정 단계에서 자신의 코드를 추가할 수 잇는 기회를 제공한다.
라이프사이클 훅의 종류에는 created, mounted, updated, ummounted가 있다.
모든 라이프사이클 훅에서는 Vue인스턴스를 가르키는 this
컨텍스트와 함께 호출이 된다.
사이클 훅 중 created, mounted가 가장 중요하다.
이때, 라이프사이클 훅을 작성하는 순서 자체는 문제가 되지 않는다.
아래의 예시에서 created와 mounted가 어떻게 활용되는지 알아보자.
<template>
<h1>{{ count }}</h1>
</template>
<script>
export default {
data() {
return {
count: 2
}
},
beforeCreate() { // 활용도가 적음
console.log('Before Create!', this.count); // undefined, 데이터가 정의되기 전에 실행 되므로 undefined가 나온다.
},
created() { // 활용도가 높음
console.log('Created!', this.count); // 2, 생성 직후라 데이터가 출력이 된다.
console.log(document.querySelector('h1')); // null, html과 연결이 되기 전이기 때문에 검색을 할 수 없다.
},
beforeMount() { // 활용도가 적음
console.log('Before Mounte!');
console.log(document.querySelector('h1')); // null, html과 연결이 되기 전이기 때문에 검색을 할 수 없다.
},
mounted() { // 활용도가 높음
console.log('Mounted!');
console.log(document.querySelector('h1')); // <h1>2</h1>, 화면에 렌더링 된 후를 조회하려면 mounted에서 확인해야 한다.
}
}
</script>
데이터를 갱신하면 연결되어 있는 화면도 갱신되어 진다는 것인데 이것을 반응성(Reactivity)이라 한다.
1-1 예제에서 비슷한 내용의 예제가 나올 것이다.
<template>
<h1 @click="increase">
{{ count }}
</h1>
</template>
<script>
export default {
data() {
return {
// 반응성(Reactivity): 데이터를 갱신하면 화면도 바뀐다.
count: 0
}
},
methods: {
increase() {
// this는 App.vue에 있는 script부분을 지칭한다.
this.count += 1;
}
}
}
</script>
<style lang="scss">
h1 {
font-size: 50px;
color: royalblue;
}
ul{
li {
font-size: 40px;
}
}
</style>
데이터 바인딩의 가장 기본 형태는 "{{ }}"(Mustache, 이중 중괄호 구문)기법을 사용한 문자열 보간법이다.
<span>메세지: {{ msg }}</span>
Mustache 태그는 해당 컴포넌트 인스턴스의 msg
속성 값으로 대체된다. 또한 msg
속성이 변경될 때 마다 갱신이 된다(반응성).
v-once
디렉티브를 사용하면 최초의 화면 렌더링 이후에는 데이터의 수정과 관계 없이 화면을 갱신하지 않는다.(반응성x)
<span v-once>{{ msg }}</span>
다음은 v-once
를 이용한 예시이다.
<template>
<h1
v-once
@click="add">
{{ msg }}
</h1>
</template>
<script>
export default {
data() {
return {
msg: 'Hello world!!'
}
},
methods: {
add() {
this.msg += '!'
}
}
}
</script>
@click="add"
를 통해서 해당 메세지를 누르면 '!'를 더하는 기능을 추가한 예시이다.
v-once
가 없다면 msg
를 누를 경우 계속해서 '!'가 추가되는 것을 볼 수 있는데 v-once
를 추가 함으로써 눌러도 반응이 없게 된다.
이중 중괄호는 데이터를 HTML이 아닌 일반 텍스트로 해석한다. 실제 HTML을 출력하려면 v-html
디렉티브를 사용해야 한다.
<span v-html="rawHtml"></span>
아래는 v-html
을 사용한 예시이다.
<template>
<h1
v-once
@click="add">
{{ msg }}
</h1>
<h1 v-html="msg"></h1>
</template>
<script>
export default {
data() {
return {
msg: '<div style="color: red;">Hello!!</div>'
}
},
methods: {
add() {
this.msg += '!'
}
}
}
</script>
v-html
을 사용하지 않은 첫 번째 h1태그에서는 <div style="color: red;">Hello!!</div>
가 그대로 출력이 된다.
v-html
을 사용한 두 번째 h1태그 에서는 Hello!!에 style이 적용되어 출력된다.
이중 중괄호 구문은 HTML 속성에 사용할 수 없다. 대신 v-bind
디렉티브를 사용하자.
<div v-bind:id="dynamicId"></div>
아래는 v-bind
에 대한 예시이다.
<template>
<h1 :class="msg">
<!--<h1 v-bind:class="msg">-->
{{ msg }}
</h1>
</template>
<script>
export default {
data() {
return {
msg: 'active'
}
},
methods: {
add() {
this.msg += '!'
}
}
}
</script>
<style scoped>
.active {
color: royalblue;
font-size: 100px;
}
</style>
디렉티브는 v-
으로 시작되는 vue에서 제공하는 html속성이다.
일부 디렉티브는 콜론으로 표시되는 “전달인자”를 사용할 수 있다. 앞의 예시처럼 v-bind 디렉티브는 반응적으로 HTML 속성을 갱신하는데 사용된다.
<a v-bind:href="url"> ... </a>
여기서 href는 전달인자로, 엘리먼트의 href 속성을 표현식 url의 값에 바인드하는 v-bind 디렉티브에게 알려준다.
또 다른 예로 DOM 이벤트를 수신하는 v-on 디렉티브이다.
<a v-on:click="doSomething"> ... </a>
전달인자는 이벤트를 받을 이름이다.
속성의 이름 부분을 대괄호로 데이터에 정의 해놓은 그 데이터를 연결해서 사용한다.
속성의 이름을 대체해서 사용할 수 있다.
아래의 예시에서는
:[attr]="msg"
를 그대로 작성해서 사용하는 경우 이벤트 발생 시 '!'가 붙으면서 '!'가 붙은 해당 클래스 선택자가 없기 때문에 스타일이 제거되는 현상이 일어난다.'active'
로 변경해준다. 이렇게 되면 하나의 문자 데이터로 해석되기 때문에 msg라는 데이터의 영향을 받지 않게 된다.<template>
<h1
:[attr]="'active'"
@[event]="add">
{{ msg }}
</h1>
</template>
<script>
export default {
data() {
return {
// 동적 전달인자
msg: 'active',
attr: 'class',
event: 'click'
}
},
methods: {
add() {
this.msg += '!'
}
}
}
</script>
<style scoped>
.active {
color: royalblue;
font-size: 100px;
}
</style>
v-bind
약어v-bind
가 사라지는 것을 볼 수 있다.v-bind
의 약어 표기법은 :만 작성하고 v-bind
는생략이 가능하다.<!-- 약어 사용 X -->
<h1 v-bind:class="msg">
<!-- 약어 사용 O -->
<h1 :class="msg">
v-on
약어v-on
디렉티브를 사용하여 DOM 이벤트를 듣고 트리거 될 때 Javascript를 실행할 수 있다.v-on
은 맨 처음 1-1. 예시에서 @click
과 관련이 있다.v-on
:을 생략하고 '@'만을 사용한다.<!-- 약어 사용 X -->
<h1 v-on:click="increase">
<!-- 약어 사용 O -->
<h1 @click="increase">
태그 내부에 v-for="변수이름 in 배열이름" :key="변수이름"
태그 안에 {{ 데이터(변수이름) }}를 작성하면 된다.
<template>
<ul>
<li
v-for="fruit in fruits"
:key="fruit"
:name="fruit">
{{ fruit }}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
fruits: ['Apple', 'Banana', 'Cherry']
}
}
}
</script>
<style lang="scss">
ul{
li {
font-size: 40px;
}
}
</style>