728x90
★ Vue 인스턴스 개요
- const vm = Vue.createApp과 같이 메서드로 만든 객체들을 자주 사용한다.
- 이처럼 Vue.creatApp 메서드를 호출하여, 만들어진 객체를 애플리케이션 인스턴스라고 부른다.
- 여기서 사용된, name, data 옵션이 바로, 옵션 객체 이다.
var vm = Vue.createApp({
name : "App",
data() {
return { name : "" };
}
}).mount('#app')
1. data 옵션
- 컴포넌트가 관리하고 추적해야 할 데이터를 등록할 때 사용한다.
- 관리와 추적의 의미는 변경을 탐지하고 추적하여, 화면을 갱신하겠다는 의미.
- 컴포넌트 인스턴스에서 $로 시작하는 이름은 인스턴스 내부에서 특수한 용도로 사용된다는 의미.
- 따라서 $,_로 시작하는 이름을 data 객체의 명으로 사용하면 안된다.
<body>
<div id='app'>
<input id="a" type="text" v-model="$name">
<br />
입력하신 이름 : <span>{{$name}}</span>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name: "App",
data() {
return { $name : "" };
}
}).mount('#app')
</script>
</body>
- $,_로 시작하는 data 속성 사용 오류가 발생된다.
2. 계산된 속성(Computed Property)
- data나 다른 속성이 변경될 때 함수가 실행되어 저장된 캐싱된 값.
- 함수의 실행은 의존하고 있는 속성 또는 data가 변경될 때 한 번 호출 된다.
- this.num이 바뀌면, computed에 등록된 sum() 함수가 호출되고 리턴된 값을 sum에 캐싱한다.
- 따라서 화면에 여러번 동일한 값을 렌더링 하더라도 sum() 함수는 단 한번만 호출된다.
<body>
<div id="app">
1보다 큰수 : <input id="a" type="text" v-model.number="num">
<br />
1부터 입력한 값까지의 합 : <span>{{sum}}</span> <br />
1부터 입력한 값까지의 합 : <span>{{sum}}</span> <br />
1부터 입력한 값까지의 합 : <span>{{sum}}</span> <br />
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return {
num : 0
};
},
computed : {
sum() {
console.log("## num : " + this.num)
var n = parseInt(this.num);
if(Number.isNaN(n)) return 0;
return (n * (n+1))/2
}
}
}).mount('#app')
</script>
</body>
- 계산된 속성은 읽기 전용이라 생각하기 쉽지만, set 메서드를 지정하면 쓰기 작업도 가능하다.
- 자바 언어 -> getter/setter 메서드랑 비슷
- get 메소드 : 정규 표현식을 사용해 데이터 속성인 amt 값에숫자 3자리마다 쉼표를 넣어서 리턴하도록 함.
- set 메소드 : 문자열을 입력받으면 쉽표(,)를 제거한 뒤 숫자 값으로 변환하여 amt 데이터에 할당한다.
- 하지만, 실제로는 get 기능만을 제공할 목적으로 계산된 속성을 사용한느 경우가 많다.
- 따라서, 계산된 속성은 기존 데이터를 이용해 읽기 전용의 값을 만들어내기 위해 자주 사용한다.
<body>
<div id="app">
<input type="text" v-model.number="amt"> <br />
금액 : <span>{{ amount }} 원</span>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return {
amt : 99999
}
},
computed : {
amount : {
get() {
var regexp = /\B(?=(\d{3})+(?!\d))/g;
return this.amt.toString().replace(regexp, ',');
},
set(amount) {
var amt = parseInt(amount.replace(/,/g,""));
this.amt = Number.isNaN(amt) ? 0 : amt
}
}
}
}).mount("#app")
</script>
</body>
3. 메서드
- Vue 인스턴스에 사용할 메서드를 등록하는 옵션.
- Vue 인스턴스를 이용해 직접 호출할 수도 있고, 디렉티브 표현식, 콧수염 표현식에서도 사용할 수 있음.
- 이벤트 핸들러로도 이용 가능함.
- 메서드는 템플릿에서 {{sum()}}과 같이 메서드의 호출 구문을 사용했기 때문에 템플릿으로 렌더링할 때 호출된다.
- 반면 계산된 속성은 데이터가 변경되면 미리 호출하여 캐싱해둔 값을 렌더링할 때 반복적으로 사용한다.
- 주의 사항 : 메서드 작성 시 화살표 함수를 메서드로 등록할 경우, this에 접근 할수 없다.
- 따라서, 메서드가 컴포넌트 인스턴스에 접근해야 한다면, 순수 자바스크립트 함수로 작성해야 한다.
<body>
<div id="app">
1보다 큰수 : <input id="a" type="text" v-model.number="num">
<br />
1부터 입력한 값까지의 합 : <span>{{sum()}}</span> <br />
1부터 입력한 값까지의 합 : <span>{{sum()}}</span> <br />
1부터 입력한 값까지의 합 : <span>{{sum()}}</span> <br />
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return {num : 0 }
},
methods : {
sum() {
console.log("## num : " + this.num)
var n = parseInt(this.num);
if (Number.isNaN(n)) return 0;
return (n * (n+1))/2
}
}
}).mount("#app")
</script>
</body>
4. 관찰 속성
- 관찰 속성(Watched Property)라는 것을 사용할 수 있다.
- 주로 긴 처리 시간이 필요한 비동기 처리에 적합하다는 특징을 가지고 있다.
- watch 옵션을 사용해, 두 개의 인자 값에 대한 값을 전달.
- current : 첫 번째 인자, old : 두 번째 인자
<body>
<div id="app">
x : <input type="text" v-model="x" /><br />
y : <input type="text" v-model="y" /><br />
덧셈 결과 : {{sum}}
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return { x : 0, y : 0, sum : 0 }
},
watch : {
x(current , old) {
console.log(`## x : ${old} --> ${current} `)
var result = Number(current) + Number(this.y);
if (isNaN(result)) this.sum = 0;
else this.sum = result;
},
y(current , old) {
console.log(`## y : ${old} --> ${current} `)
var result = Number(this.x) + Number(current);
if (isNaN(result)) this.sum = 0;
else this.sum = result;
}
}
}).mount("#app")
</script>
</body>
- 상위의 기능은 관찰 속성을 사용하지 않고, 계산하는 것이 더 편리함.
- 하지만, 긴 시간을 요구하는 비동기 처리가 필요할 때는 계산된 속성은 사용할 수 없으며, 관찰 속성을 사용해야 한다.
var vm = Vue.createApp({
name : "App",
data() {
return { x:0, y:0 }
},
computed : {
sum() {
let result = Number(this.x) + Number(this.y);
if (isNaN(result)) result 0;
else return result;
}
}
}).mount('#app')
- 연락처를 활용한 관찰 속성 사용
- _.debounce() : 짧은 시간에 너무 많은 API 요청이 일어나는 것을 막는다.
- fetchContacts : 두 글자 이상 입력되었다면, 해당 함수를 호출 -> axios.get() 함수를 이용해 이름 검색을 수행
- axios, get() 메서드를 호출하여 서비스 API로 요청하고 1초 이상의 시간이 흐른 후 API로 부터 응답이 오면 then()의 인자로 전달된 함수가 호출된다.
- 응답이 온 후에 Vue 객체의 contacts 데이터가 변경되고, 이것은 다시 UI에 v-for문을 통해 <li> 태그로 화면에 즉시 나타난다.
<body>
<div id="app">
이름 : <input type="text" v-model.trim="name"
placeholder="영문 두글자 이상을 입력하세요."/><br />
<ul>
<li v-for="c in contacts">{{c.name}} : {{c.tel}}</li>
</ul>
<div v-show="isLoding">검색중</div>
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript" src="https://unpkg.com/axios"></script>
<script type="text/javascript" src="https://unpkg.com/lodash"></script>
<script type="text/javascript">
const BASEURL = "https://contactsvc.bmaster.kro.kr";
var vm = Vue.createApp({
name : "App",
data() {
return { name : "", contacts : [], isLoding : false}
},
watch : {
name(current) {
if (current.length >=2) {
this.fetchContacts();
}else {
this.contacts = [];
}
}
},
methods : {
fetchContacts : _.debounce(function() {
this.isLoding = true;
axios.get(BASEURL + `/contacts_long/search/${this.name}`)
.then((response)=>{
this.isLoding = false;
this.contacts = response.data;
})
}, 300)
}
}).mount("#app")
</script>
</body>
- 관찰 속성이 비동기 처리와 같은 경우에는 장점이 있다. 하지만, 사용은 자제하는 편이 좋다.
- 관찰 속성의 남용은 data에 대한 의존 관계가 복잡해져서 코드의 실행 흐름을 분석하기 어려워지고 디버깅이 까다로워지기 때문에 관찰 속성을 대신하여 메서드 + 이벤트 조합을 사용할 것을 권장한다.
5. 생명주기 메서드
생명주기 메서드 | 설명 |
beforeCreate | 인스턴스가 초기화된 후, 데이터에 대한 관찰 기능, 이벤트가 설정되기 전에 동기적으로 호출된다. |
created | 인스턴스 생성이 완료된 후 동기적으로 호출됨. 이 메서드가 호출되기 직전에 데이터 관찰 기능, 계산된 속성, 메서드, 이벤트 초기화 등이 모두 완료된다. |
beforeMount | 마운팅이 시작되기 직전에 호출됨. 마운팅은 render 함수가 처음 실행되어 DOM 트리에 컴포넌트의 렌더링 결과가 추가되는 상태. |
mounted | Vue.createApp().mount에 의해 컴포넌트 인스턴스가 HTML Document의 요소에 마운트된 후에 호출된다. |
beforeUpdate | 데이터가 변경되고 DOM이 패치되기 전에 호출됨. 업데이트 전에 기존 DOM 트리에 접근할 수 있는 좋은 시점. |
updated | 데이터의 변경으로 가상 DOM이 렌더링되고 패치 된 후에 호출된다. |
beforeUnmount | 컴포넌트 인스턴스가 언마운트 되기 직전에 호출된다. 이 시점에는 인스턴스의 모든 기능이 사용할 수 있다. |
unmounted | 컴포넌트 인스턴스가 언마운트된 후에 호출된다. 이 시점에는 컴포넌트의 모든 디렉티브들의 연결이 해제되고, 모든 이벤트 리스너 제거, 자식 컴포넌트들도 언마운트된 상태 |
errorCaptured | 생명주기 메서드가 설정된 컴포넌트의 자식 컴포넌트 트리에서 오류가 발생하면 컴포넌트 트리를 거슬러 올라와서 이 메서드가 실행된다. |
- created, mounted 메서드가 순차적으로 실행되고, num 데이터가 변경될 때마다 update 메서드가 호출됨.
- before~로 시작하는 것은 부모쪽이 먼저 실행되고 ~ed로 끝나는 생명주기 메서드는 자식쪽이 먼저 실행됨.
<body>
<div id="app">
1보다 큰수 : <input id="a" type="text" v-model.number="num">
<br />
1부터 입력한 값까지의 합 : <span>{{sum}}</span> <br />
1부터 입력한 값까지의 합 : <span>{{sum}}</span> <br />
1부터 입력한 값까지의 합 : <span>{{sum}}</span> <br />
</div>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name : "App",
data() {
return { num : 0 };
},
created() {
console.log("## created")
},
mounted() {
console.log("## mounted")
},
updated() {
console.log("## updated")
},
computed : {
sum() {
var n = parseInt(this.num);
if (Number.isNaN(n)) return 0;
return (n * (n+1))/2
}
}
}).mount('#app')
</script>
</body>
- Tip : 프로젝트 수준이나 주요 모듈 단위로 정의해서 중앙 집중화된 에러 처리를 수행하는 것이 바람직하다.
- errorCaptured 생명주기 메서드는 자기 자신 컴포넌트에서 발생한 오류는 잡아내지 못한다는 점은 주의해야한다.
728x90
'Vue.js' 카테고리의 다른 글
Vue.js 3.0 STEP 4 - 스타일 적용 (0) | 2024.01.25 |
---|---|
Vue.js 3.0 STEP 3 - 이벤트 처리 (0) | 2024.01.18 |
Vue.js 3.0 STEP 1 - Vue.js 기초와 Template (0) | 2024.01.17 |
ES6 STEP 2 - 기본 문법 2 (0) | 2024.01.17 |
ES6 STEP 1 - 기본 문법 (0) | 2024.01.16 |