Daehyunii's Dev-blog
[데브코스] TIL-119 Vue, 라이프 사이클, 템플릿 문법, Proxy 본문
[데브코스] TIL-119 Vue, 라이프 사이클, 템플릿 문법, Proxy
Daehyunii 2022. 12. 7. 23:31Vue란?
사용자 인터페이스를 만들기 위한 프로그레시브 자바스크립트 프레임워크이다. Vue 3 버전이 현재 가장 최신 버전이며, Vue 2 버전에서 Vue 3 버전으로 넘어가고 있는 과도기이다. 핵심 라이브러리는 뷰 레이어만 초점을 맞추어 다른 라이브러리나 기존 프로젝트와 통합이 쉽다. 레이아웃을 처리하는데 유용하다.
1. 선언적 렌더링
간단한 템플릿 구문을 사용하여 DOM에서 데이터를 선언적으로 렌더링할 수 있다. 데이터와 DOM이 연결되었으며 반응형 데이터가 되었다고 말할 수 있다. 데이터가 바뀔 때 연결되어 있는 화면도 바뀌는 것을 반응성이라고 한다. 반응형 데이터를 선언하고 화면에 렌더링해보자. 참고로 setInterval() 콜백함수는 this가 참조하는 곳이 달라질 수 있기 때문에 화살표함수로 작성해야한다. 화살표함수는 함수가 선언되는 위치에서 this가 정의되어 원하는 곳을 참조할 수 있다.
const App = {
data() {
return {
counter: 0,
};
},
mounted() {
setInterval(() => {
this.counter += 1;
}, 1000);
},
};
Vue.createApp(App).mount('#app');
이중 중괄호 구문에 아래와 같이 데이터를 넣어주면 된다.
<div id="app">{{ counter }}</div>
텍스트 보간처럼 v-bind라는 디렉티브를 사용하여 HTML 속성에 데이터를 연결해줄 수 있다. 디렉티브는 Vue에서 제공하는 특수 속성임을 나타내기 위해 v- 접두어를 사용한다. 이는 렌더링 된 DOM에 특수한 반응형 동작한다.
2. 사용자 입력 핸들링
v-on 디렉티브를 통해 이벤트 리스너를 추가할 수 있다. methods 안에 실행할 함수를 생성하고 HTML 속성에 연결시켜주면 된다.
3. 폼 입력 바인딩
v-model 디렉티브를 통해 양방향 바인딩을 할 수 있다. 보통 input, form 등이 있다.
4. 조건문과 반복문
v-if
- boolean 값에 따라 화면에 보임
v-for
- 매개변수 in 배열/객체
5. 컴포넌트로 조립하기
컴포넌트 시스템은 Vue에서 중요한 개념이다. 작고 독립적이며 재사용할 수 있는 컴포넌트로 구성된 대규모 애플리케이션을 구축할 수 있게 해주는 추상적 개념이다. Vue에서 컴포넌트는 미리 정의된 옵션을 가진 Vue 인스턴스이다.
6. 애플리케이션과 인스턴스 생성
6.1 애플리케이션 API
Vue의 동작을 전역적으로 변경하는 API가 Vue3의 새로운 createApp() 메서드에 의해 생성된 애플리케이션 인스턴스로 이동한다. 메서드 안에 객체로 여러 옵션들을 전달해줄 수 있다.
import { createApp } from 'vue'
const app = createApp({})
6.2 mount()
루트 컴포넌트 인스턴스를 반환하는 메서드이다. 애플리케이션 루트 컴포넌트의 템플릿을 렌더링하여, 제시된 DOM 엘리먼트의 innerHTML을 치환한다.
import { createApp } from 'vue'
const app = createApp({})
app.mount('#app')
6.3 인스턴스 속성과 메서드
위의 코드에서 app.mount('#app') 가 실행되면 인스턴스가 반환된다. 인스턴스를 뷰모델이라고도 부른다. 인스턴스에서 사용할 수 있는 여러 속성과 메서드들이 있다. 필요한 경우 바로 호출하여 사용할 수 있다.
라이프 사이클
1. 라이프 사이클 다이어그램
2. 라이프 사이클 훅
각 컴포넌트는 생성될 때 일련의 초기화 단계를 거친다. 예를 들어, 데이터를 관찰하거나 데이터가 바뀔 때 DOM을 업데이트를 해야한다. 그 과정에서 라이프사이클 훅이라는 함수를 실행하여 사용자가 특정 단계에서 자신의 코드를 추가할 수 있도록 한다. beforeCreate(), created(), beforeMount(), mounted() beforeCreate()에는 this를 통해 데이터에 접근하지 못한다. createApp()이 되기 전에 동작해야하는 일을 작성하는데 거의 사용할 일이 없다. 보통 created()와 mounted()를 많이 사용하는데, 먼저 created()의 사용을 고려하는 것이 개발 시에 두 개념을 헷갈리지 않고 적용할 수 있을 것이다.
// Vue 애플리케이션이 만들어지기 직전
beforeCreate() {
console.log('beforeCreate!', this.msg);
},
// Vue 애플리케이션이 만들어진 직후
created() {
console.log('created!', this.msg);
},
// HTML DOM과 연결되기 직전
beforeMount() {
console.log('beforeMount!', this.msg);
},
// HTML DOM과 연결된 직후
mounted() {
console.log('mounted!', this.msg);
},
console.log →
// Vue 애플리케이션이 만들어지기 직전
beforeCreate() {
console.log(document.querySelector('h1'));
},
// Vue 애플리케이션이 만들어진 직후
created() {
console.log(document.querySelector('h1'));
},
// HTML과 연결되기 직전
beforeMount() {
console.log(document.querySelector('h1'));
},
// HTML과 연결된 직후
mounted() {
console.log(document.querySelector('h1'));
},
console.log →
beforeUpdate(), updated()
여기서 업데이트는 데이터의 업데이트를 의미하는 것이 아닌, 화면의 업데이트를 의미한다.
// 화면이 업데이트 되기 전
beforeUpdate() {
console.log('beforeUpdate!', this.msg);
console.log(document.querySelector('h1').textContent);
},
// 화면이 업데이트 된 후
updated() {
console.log('updated!', this.msg);
console.log(document.querySelector('h1').textContent);
},
console.log →
beforeUnmount(), unmounted()
app.unmount()를 통해 HTML과의 연결을 해제해준다. 실제로는 강제로 해제하는 경우가 많지 않지만, 테스트를 위해 해제해주면 다음과 같은 결과를 확인할 수 있다. 데이터는 그대로 남아있으며 다시 사용할 수 있지만 화면과 연결이 끊겼기 때문에 화면에 보여지지는 않는다.
// HTML과 연결이 해제되기 직전
beforeUnmount() {
console.log('beforeUnmount!', this.msg);
},
// HTML과 연결이 해제된 직후
unmounted() {
console.log('unmounted!', this.msg);
},
console.log →
3. 템플릿 문법
Vue에서 사용하는 템플릿 문법에 대해 알아보자. 데이터가 변경됐을 때 화면이 바뀌는 것이 Vue 내부의 최적화를 통해 DOM 조작이 최소화된다.
4. 이중 중괄호 구문
문자열 보간법으로 데이터가 변경될 때 마다 갱신된다. 내부에서 자바스크립트의 단일 표현식을 지원한다. 예를 들면 삼항 연산자가 있다.
<div id="app">
<h1>{{ msg }}</h1>
</div>
v-once 디렉티브를 추가하면 데이터가 변경되어도 갱신되지 않는 일회성 보간이 수행된다. 반응성을 가지지 않게 된다. v-html 디렉티브를 추가하면 이중 중괄호의 데이터를 일반 텍스트가 아닌 HTML로 해석된다. 이 디렉티브를 사용할 때는 주의할 점이 있다. 웹 사이트에서 임의의 HTML을 동적으로 렌더링하면 XSS(Cross-site_scripting) 취약점으로 이어줄 수 있고, 매우 위험할 수 있다.
4.1 속성
이중 중괄호 구문은 HTML 속성 부분에 사용할 수 없다. 이를 대신하여 v-bind 디렉티브를 사용하면 된다.
<div id="app">
<h1 v-bind:class="name">{{ msg }}</h1>
<input type="text" v-bind:value="msg" v-bind:disabled="disabled" />
</div>
4.2 디렉티브
전달인자
일부 디렉티브는 디렉티브명 뒤에 콜론으로 표기되는 전달인자를 가질 수 있다. 예를 들어 DOM 이벤트를 수신하는 v-on 디렉티브가 있다.
<a v-on:click="increase">...</a>
동적 전달인자
자바스크립트 표현식을 대괄호로 묶어 디렉티브 전달인자로 사용할 수 있다.
<a v-on:[eventName]="increase">...</a>
아래에서 text라는 값은 텍스트로 전달되야 하기 때문에 소괄호로 한 번 더 묶어줘야 한다.
<input v-bind:[attr]="'text'" />
4.3 약어
자주 사용되는 두 개의 디렉티브 v-bind와 v-on에 대한 특별한 약어를 제공한다.
v-bind:의 약어는 :이다.
<input :[attr]="'text'" />
v-on: 약어는 @이다.
<a @[eventName]="increase">...</a>
Data와 Methods
1. data
data는 함수 안에서 return 키워드로 반환해야 한다. 반응성을 유지하려면 data 옵션에 초기값과 상관 없이 미리 선언해두어야 한다.
const App = {
data() {
return {
count: 0,
};
},
};
const vm = Vue.createApp(App).mount('#app');
프록시 객체는 기본적인 동작(속성 접근, 할당, 순회, 열거, 함수 호출 등) 새로운 행동을 정의할 때 사용한다.
new Proxy(target, handler)
target 행동을 감시할 곳 handler 행동을 감시해서 처리할 로직이 포함된 객체 Vue가 프록시를 활용해서 반응형 데이터에 값을 할당하게 되면 화면을 바꾸는 로직이 있는 set() 부분이 동작한다. 데이터의 조회와 데이터의 갱신을 감시해서 상황이 발생하면 중간에 로직을 추가할 수 있다. get()과 set()의 target은 app.data이며, key는 count이다.
// 컴포넌트
const app = {
data() {
return {
count: 0,
};
},
};
// target, handler
const proxyA = new Proxy(app.data(), {
get(target, key) {
console.log('Getter!', target, key);
return target[key];
},
set(target, key, value) {
console.log('Setter!', target, key, value);
target[key] = value;
},
});
2. methods
컴포넌트 인스턴스에 메서드를 추가하려면 methods 옵션을 사용하면 된다. 동작하기를 원하는 메서드들이 담긴 하나의 객체여야 한다.
methods 안에서 컴포넌트 인스턴스를 항상 참조할 수 있도록 this 값을 자동으로 바인딩한다. 여기서 this는 뷰의 인스턴스를 참조한다. methods 정의할 때만 화살표 함수를 사용하면 this 값을 바인딩하지 못하기 때문에 일반 함수로 정의해야 한다. 이벤트에 메서드를 호출할 때는 호출기호를 생략할 수 있다.
3. 디바운싱과 쓰로틀링
Vue에서는 자체적으로 지원하지 않는다. 그래서 Lodash와 같은 라이브러리를 사용하면 된다.
오늘을 마무리 하며
Vue 프레임워크에 대한 강의가 시작되었다. React 관련 강의를 먼저 시작할 것이라고 생각했는데 Vue에 대해서 먼저 공부하게 되어서 적지않은 당황을 했던 것 같다. 사실 나는 자바스크립트 기본 문법에 대해서만 공부를 한 상태였고 지금까지도 자바스크립트와 관련된 강의만 이어졌었다. 그러다 이제는 자바스크립트 기반의 프레임워크인 Vue에 대해서 접하게 되니 많이 혼란스러운 부분이 많이 있다. 아직 프레임워크와 라이브러리에 대한 차이점에 대해서도 정확하게 인지가 되지 않았고 자바스크립트를 기반으로 프레임워크를 작성한다는 개념도 정확하게 인지하지 못한 상태이다. 어렴풋하게 이해하기로는 프레임워크는 정해진 규칙에 맞춰서 내가 코드를 작성하면 된다는 것이다. 정확한 문법을 인지하는게 필요하겠지만 정확한 문법을 사용한다면 바닐라 자바스크립트를 통해서 하나 하나 전부 구현해야 하는 모든 것들을 대체해주게 된다는 점이다. 아직 혼란스러운 부분이 많이 있어 다음 강의를 통해서 감을 익혀 나가야 할 것 같다.
'✏️ 2022. TIL > December (데브코스)' 카테고리의 다른 글
[데브코스] TIL-122 Vue, Node.js, Parcel, Webpack, 컴포넌트 (0) | 2022.12.15 |
---|---|
[데브코스] TIL-121 Vue, 렌더링, 이벤트, 폼 입력 바인딩, 컴포넌트 (0) | 2022.12.15 |
[데브코스] TIL-120 Vue, Computed, Watch, 클래스, 스타일 바인딩 (0) | 2022.12.13 |
[데브코스] TIL-118 SCSS, @mixin, @extend, @use, @import (0) | 2022.12.06 |
[데브코스] TIL-117 SCSS (0) | 2022.12.05 |