VueJS
Vue.js는 사용자 인터페이스를 만들기 위한 자바스크립트 프레임워크다.
CDN을 사용하여 HTML의 상단에 script를 불러와서 간단하게 사용할 수 있다.
<script src="https://unpkg.com/vue@3"></script>
Vue 시작하기
반응성
<body>
<div id="app">{{ counter }}</div>
<script>
Vue.createApp({
data() {
return {
counter: 0,
};
},
mounted() {
setInterval(() => {
this.counter += 1;
}, 1000);
},
}).mount("#app");
</script>
</body>
예제의 결과를 브라우저에서 확인하면 1초마다 1이 증가하는 것을 확인할 수 있다.
현재 couter
라는 데이터와 DOM이 연결된 상태이고 이렇게 데이터가 변경이 되면 연결되어 있는 화면도 같이 변경되는 것을 반응성이라고 한다.
디렉티브
<body>
<style>
.orange {
color: orange;
}
</style>
<div id="app">
<div v-bind:class="{ orange: active }">{{ counter }}</div>
<button v-on:click="increase">Click Me!</button>
</div>
<script>
const App = {
data() {
return {
counter: 0,
active: true,
};
},
methods: {
increase() {
this.counter += 1;
}
}
};
const app = Vue.createApp(App).mount("#app");
</script>
</body>
v-
로 시작하는 속성들을 디렉티브라고 부른다.
디렉티브는 VueJS의 문법으로 렌더링 된 DOM에 반응형 동작을 하도록 도와준다.
v-bind
디렉티브를 사용하여 html의 속성에 view model의 데이터를 연결할 수 있다. 약어는:
이다.v-on
디렉티브를 사용하여 이벤트 핸들러를 추가할 수 있다. 약어는@
이다.v-if
디렉티브를 사용하여 조건에 따라 렌더링 여부를 결정한다.v-for
디렉티브를 사용하여 이터러블 데이터를 순회할 수 있다.v-once
디렉티브를 사용하여 데이터가 변경되어도 갱신하지 않는 일회성 보간을 작성할 수 있다.v-html
디렉티브를 사용하여 이중 중괄호 구문 안에 html을 출력할 수 있다. (XSS 취약 주의)
디렉티브의 속성 이름은 동적으로 작성할 수 있다.
<body>
<div id="app">
<h1 v-bind:[attr]="'active'">Hello vue!</h1>
</div>
<script>
const App = {
data() {
return {
attr: "class",
};
},
};
const vm = Vue.createApp(App).mount("#app");
</script>
</body>
예제
<body>
<div id="app">
<div v-if="active">Hello Vue!</div>
<button v-on:click="toggle">Toggle</button>
</div>
<script>
const App = {
data() {
return {
active: false,
};
},
methods: {
toggle() {
this.active = !this.active;
},
},
};
const app = Vue.createApp(App).mount("#app");
</script>
</body>
원리
Hello Vue!
라는 텍스트를 가지고 있는 div에 v-if
라는 디렉티브를 추가해서 active라는 데이터를 연결한다.
그리고 이 데이터를 toggle
이라는 메소드를 통해 반대되는 값으로 변경한다.
true 혹은 false 값을 지니게 되는데 그 값을 v-if
가 판단해서 true라면 화면에 출력하고 false라는 출력하지 않는다.
컴포넌트
<script>
const FruitItem = {
template: "<li>{{ fruitName }}</li>",
props: ["fruitName"],
};
const App = {
components: {
FruitItem,
},
data() {
return ;
},
};
const app = Vue.createApp(App).mount("#app");
</script>
FruitItem
이라는 객체를 만들고 template과 props 속성을 작성한다.
props로 받을 데이터의 이름을 정해주고 template에 전달을 해주는 개념이다.
component 이름은 파스칼 케이스, props 이름은 카멜 케이스로 작성한다.
App에는 components 객체를 만들고 생성한 컴포넌트를 작성한다.
<div id="app">
<ul>
<fruit-item fruit-name="Orange"></fruit-item>
</ul>
</div>
components에 정의한 컴포넌트를 HTML에서 사용하려면 컴포넌트 이름의 태그를 만들고 props에 전달할 데이터를 작성한다.
태그명과 전달해줄 데이터는 케밥 케이스로 작성한다.
라이프 사이클
Vue 컴포넌트 인스턴스는 생성될 때 일련의 초기화 단계를 거친다.
이 과정에서 라이프 사이클 훅 함수를 사용할 수 있다.
beforeCreate() {
// VueJS 어플리케이션이 생성되기 전
},
created() {
// VueJS 어플리케이션이 생성된 직후
},
beforeMount() {
// DOM element 연결되기 직전
},
mounted() {
// DOM element 연결된 직후
},
beforeUpdate() {
// 데이터 변경 후 화면이 업데이트 되기 전 (데이터가 업데이트 되기 전이 아님)
},
updated() {
// 데이터와 화면 모두 변경사항이 반영된 직후
},
beforeUnmount() {
// DOM element와 연결이 끊기기 직전
},
unmounted() {
// DOM element와 연결이 끊어진 후
},
템플릿 문법
이중 중괄호 구문 {{ }}
을 사용하여 문자열 보간 기능을 사용할 수 있다.
<p>메세지: {{ message }}</p>
위 코드의 이중 중괄호 구문은 컴포넌트 인스턴스의 message
속성 값으로 대체되며, 속성 값이 변경될때마다 갱신된다.
<h1 v-bind:class="name">{{ name + '입니다' }}</h1>
<h1>{{ count + 100 }}</h1>
이중 중괄호 구문 내에서는 단일 표현식을 지원한다.
Data & Methods
Data
VueJS는 반응형 데이터에 접근할 때 $data
라는 내장 객체에 접근해서 확인할 수 있다.
const app = Vue.createApp({
data() {
return { count: 4 }
}
})
const vm = app.mount('#app')
console.log(vm.$data.count) // => 4
console.log(vm.count) // => 4
vm.count = 5
console.log(vm.$data.count) // => 5
vm.$data.count = 6
console.log(vm.count) // => 6
인스턴스 속성은 인스턴스가 처음 생성될 때만 추가되므로 원하는 값을 사용할 수 없는 속성에는 null
, undefined
같은 값을 주어 초기화하는 것이 좋다.
새로운 속성을 data에 포함하지 않고 컴포넌트 인스턴스에 직접 추가할 수 있지만 이렇게 추가한 속성은 반응형 $data 객체로 처리되지 않기 때문에 Vue의 반응형 시스템에 의해 자동으로 추적되지 않는다.
Proxy
Proxy는 특정 데이터가 언제 조회되고 언제 값이 할당되는지 감시한다.
따라서 proxy를 통해 화면에 출력되는 로직을 담당할 수 있다.
const app = {
data: {
count: 0,
},
};
// Proxy(target, handler)
// target: 감시할 데이터
// handler: 데이터를 가져와서 조작한 후 반환 가능
const proxyA = new Proxy(app.data, {
get(target, key) {
console.log("Getter");
return target[key];
},
set(target, key, value) {
console.log("setter");
target[key] = value * 2;
},
});
const proxyB = new Proxy(app.data, {
get(target, key) {
console.log("Getter");
return target[key];
},
set(target, key, value) {
console.log("setter");
target[key] = value * 2;
},
});
위 코드에서 data가 객체(= 참조형 데이터)이므로 proxyA에서 count의 값이 바뀌면 proxyB에도 영향이 미친다.
그렇기 때문에 data 옵션은 함수를 반환해야 한다.
const app = {
data() {
return {
count: 0,
};
},
};
Methods
컴포넌트 인스턴스에 함수를 추가하기 위해 methods를 사용할 수 있다.
const App = {
data() {
return {
count: 0,
};
},
methods: {
increase() {
this.count += 1; // this는 vm
},
},
};
method를 선언할 때 화살표 함수를 사용하면 Vue가 적절한 this 값을 바인딩하지 못한다.
따라서 함수를 정의할 때는 화살표 함수를 사용하지 말아야 한다.
함수 내부에서 사용하는 것은 상관없다.
- 일반 함수의 this는 함수가 실행될 때 정의된다.
- 화살표 함수의 this는 함수가 만들어질 때 정의된다.
출처: 프로그래머스 프론트엔드 데브코스
[Day 33] Vue (1)
'데브코스' 카테고리의 다른 글
[Day 35] 렌더링, 이벤트 핸들링, 폼 바인딩, 컴포넌트 (0) | 2022.12.06 |
---|---|
[Day 34] computed, watch, 데이터 바인딩 (0) | 2022.12.05 |
[Day 32] SCSS (2) (0) | 2022.11.30 |
[Day 31] 변수, @supports, @media, SCSS (1) (0) | 2022.11.28 |
[Day 30] grid, transform, columns, filter (0) | 2022.11.25 |