728x90
반응형
Lifecycle Hooks이란?
- 컴포넌트에서 생명주기 기능(생성, 수정, 소멸)의 과정을 말한다.
- 대표적인 경우
- 템플릿을 컴파일 하는 경우
- 데이터 설정이 필요한 경우
- 컴포넌트를 dom에 마운트 하는 경우
- 데이터가 변경되어 dom을 업데이트 하는 경우
Lifecycle Hooks 단계
크게 created, mounted, updated, destroyed 4단계로 나뉘어 진다.
creation: 생성 단계
- DOM이 생성되기 전 단계
- beforeCreate, created
- 다른 훅과 달리 서버 렌더링 과정 중에도 실행이 된다.
[beforeCreate]
- 라이프사이클에서 가장 먼저 실행된다.
- 컴포넌트가 DOM에 가장 처음으로 추가되기 전 상태를 말한다.
- 컴포넌트가 DOM에 추가되기 전이기 때문에 DOM에 접근하는 this.$el을 사용할 수 없다. 즉 data가 정의되지 않았기 때문에 events, methods등을 사용할 수 없다.
- 언제사용?
- 클라이언트 렌더링 및 서버 렌더링 과정 모두에서 컴포넌트 설정이 필요할 때 처리함
- beforeCreate
- 가장 먼저 실행되는 훅이다. 컴포넌트 초기화로 아직 데이터와 이벤트가 설정되지 않은 상태이다.
[created]
- 템플릿 및 virtual DOM이 mounting 또는 rendering되기 전에 실행한다. data, events, computed, methods, watcher 가 활성화 되어 액세스 할 수 있다. 하지만 아직 DOM이 부작되지 않은 상태이기에
DOM을 조작할 순 없다.
<template>
<h1 ref="tag">{{ name }}</h1>
</template>
<script>
export default {
data() {
return {
name: '이름입니다.'
}
},
created() {
console.log(name) //이름입니다.
console.log(this.$refs.tag); // undefined
}
}
</script>
- data가 활성화 되었기에 name이 출력된다.
- DOM은 생성 전이기 때문에 ref는 undefined를 출력한다. (mounted에서 사용 가능)
- 언제사용?
- 데이터 초기화시에 사용한다.
- 부모 > 자식 순으로 created훅이 실행된다.
Mounting : DOM 삽입 단계
- DOM이 생성되는 초기 단계
- DOM을 변경하고 싶으면 해당 단계에서 사용할 수 있다.
- 가장 많이 사용하는 훅이며 렌더링 전후에 즉시 컴포넌트에 생성할 수 있다.
- 서버 렌더링이 실행되는 동안에는 실행되지 않는다.
- 언제사용?
- 초기 렌더링 직전이나 직후 DOM에 접근하거나 수정하는 경우
- 초기화시 컴포넌트에 필요한 데이터를 가져와야 하는 경우
- 서버 측 렌더링 동안 필요한 데이터가 있을 경우는 created사용
[beforeMount]
- 초기 렌더링이 일어나기 직전에 실행됨 (DOM이 생성되기 직전)
- 템플릿이나 렌더함수가 컴파일 된 후
[mounted]
- 실제 DOM이 생성되고 난 후 실행되는 단계
- DOM에 직접 접근이 가능하여 수정, 제어 할 때 사용한다.
- *자식 > 부모 순으로 mounted hook가 실행된다.
- vue가 아닌 라이브러리를 통합할 때 사용한다.
Updating: diff, re-rendering 단계
컴포넌트의 변화가 발생한 경우 감지하는 hook이다.
컴포넌트에 사용하는 반응형 속성들이 변경되거나 리렌더링 될 때마다 호출된다.
- DOM 태그 변화
- DOM 태그 속성 변화
[beforeUpdated]
- 컴포넌트에서 사용되는 data값이 변경 -> DOM에 패치 -> 다시 렌더링 직전의 훅이다.
- 주로 컴포넌트가 렌더링 되기 전에 reactivity 데이터의 신규 상태를 가져와야하는 경우에 사용한다. (reactivity data: 데이터의 변화에 따라 화면이 자동으로 그려짐)
[updated]
- 컴포넌트 데이터가 변경되어 DOM이 리렌더링 된 후 실행된다.
- 언제사용?
- 속성이 변경된 후 DOM에 접근해야 할 때 사용한다.
<template>
<h1>Component Main Page</h1>
<p v-if="isShow">update</p>
<button @click="show">버튼</button>
</template>
<script>
export default {
data(){
return{
isShow: false,
}
},
updated(){
console.log("Dom변화 발생");
},
methods: {
show(){
this.isShow = !this.isShow;
}
},
}
</script>
- 버튼 클릭 -> v-if 실행 -> <p v-if="isShow">update</p> DOM삽입 -> updated hook 감지 -> console.log 출력
Destruction : 해체 단계
- 컴포넌트가 해체되어 DOM에서 제거될 때 실행된다.
[beforeDstory]
- 해체 직전이다.
- 컴포넌트의 기능을 그대로 가지고 있는 상태
- 언제사용?
- 이벤트리스너, reative subscriptions 정리시
[destroyed]
- 컴포넌트가 소멸된 후 호출되는 hook
- 컴포넌트 기능이 모두 해체된 상태이다.
- 언제사용?
- 컴포넌트가 사라진것을 원격 서버에 알려야 하는 경우
Lifecycle Hooks 부모, 자식 호출 순서
- created: 부모 -> 자식
- mounted: 자식 -> 부모
ex) 부모컴포넌트 created => 자식컴포넌트 created => 자식컴포넌트 mounted => 부모컴포넌트 mounted
컴포넌트 mounted, updated, unmounted 예시
// 부모 컴포넌트
<template>
<h1>Ninja Reaction Timer</h1>
<button @click="start" :disabled="isPlaying">play</button>
<Block v-if="isPlaying" :delay="delay" />
</template>
<script>
import Block from "./components/Block.vue";
export default {
name: "App",
components: { Block },
data() {
return {
isPlaying: false,
delay: null,
};
},
methods: {
start() {
this.delay = 2000 + Math.random() * 5000;
this.isPlaying = true;
},
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #444;
margin-top: 60px;
}
</style>
- delay를 props로 자식에게 전달한다.
- play버튼 클릭 시 자식 컴포넌트가 받은 props(delay)가 지나면 mounted되도록 한다.
//자식 컴포넌트
<template>
<!-- 클릭한 후에만 화면에 나타나는 녹색 블록창 -->
<div class="block" v-if="showBlock">click me</div>
</template>
<script>
export default {
props: ["delay"],
data() {
return {
showBlock: false,
};
},
mounted() {
// 구성요소가 dom을 마운트 했을 때 실행하고 싶은 코드
// 마운트 될 때만 실행된다.
console.log("컴포넌트 마운트");
setTimeout(() => {
console.log(this.delay);
console.log("showBlock 변경");
this.showBlock = true;
}, this.delay);
},
updated() {
// 컴포넌트 데이터가 변경되어 dom이 리렌더링 된 후 실행됨.
// 요소가 변경된 후 dom에 접근해야할 때 사용한다.
console.log("데이터 변경완료");
},
unmounted() {
console.log("데이터 삭제");
},
};
</script>
<style>
.block {
width: 400px;
border-radius: 20px;
background: #0faf87;
color: #fff;
text-align: center;
padding: 100px 0;
margin: 40px auto;
}
</style>
728x90
'Framework > vue_Foundation' 카테고리의 다른 글
v-for Directive (0) | 2023.01.05 |
---|---|
Conditional Rendering(v-if, v-show) (0) | 2023.01.05 |
Binding(vue.js) (0) | 2023.01.05 |
vue VSCode Snippets extension (0) | 2023.01.02 |
vue3 (0) | 2022.12.13 |
댓글