Vue 인스턴스
var a = new Vue({})
와 같이 만든 객체를 Vue 인스턴스라고 하는데 처음에 배웠던 ViewModel을 의미하기도 하죠. 이 Vue 인스턴스를 생성할 때 여러 옵션을 설정할 수 있는데 이 옵션들에 대해 알아보도록 할게요.
data 옵션
var model = {
number = 2
}
var test = new Vue({
el: '#test',
data : model
});
data 옵션에 주어진 모든 속성들은 Vue인스턴스 내부에서 직접 사용되는 것이 아니라 Vue 인스턴스와 Data 옵션에 주어진 객체 사이에 프록시(대리인?)를 두어 처리해요. 그리고 data 옵션은 Vue 인스턴스가 관찰하는 데이터 객체를 의미하므로 변경 사항을 즉시 감지해요.
- 데이터에 접근하는 방법
- test.number = 3
- model.number = 4
- test.$data.number = 5
Vue 인스턴스의 내장 옵션들은 모두 $를 붙이면 접근이 가능해요.
el 옵션
제일 처음에 말씀드린 대로 el은 element의 약자로써 Vue 인스턴스에 연결할 HTML 요소를 지정해요. 여기서 조심해야할 점은 여러개 요소에 지정하면 안된다는 것이에요.
추가적으로 실행 도중 동적으로 el 옵션을 연결할 수 있지만 그리 권장하는 방법은 아니라고 하네요. Vue 인스턴스가 HTML요소와 연결되면 도중에 연결된 요소를 변경할 수 없기 때문이라고 해요. 즉 인스턴스 생성시에 미리 el옵션을 설정하는 것을 권장한다고 해요.
computed 옵션
var test = new Vue({
el : "test",
data : { num : 0 },
computed : {
multi : function() {
var a = Number(this.num);
if ( Number.isNaN(n)|| n<1) return 0;
return num*10;
}
}
});
computed
옵션은 생긴 걸 봤을 땐 함수처럼 생겼어요. 하지만 취급은 속성처럼 취급해요. computed
뜻 그대로 이미 계산된 이라고 생각하시면되요. 그렇기 때문에 접근시에도 test.multi 로 접근을 하면 0과 10을 곱한 값이 나와요. 좀 더 쉽게 생각하자면 읽기 전용이라고 생각하면 되요.
methods 옵션
var test = new Vue({
el : "test",
data : { num : 0 },
methods : {
multi : function() {
var a = Number(this.num);
if ( Number.isNaN(n)|| n<1) return 0;
return num*10;
}
}
});
이런 방법으로 등록된 method는 Vue 인스턴스를 이용한 직접 호출, 디렉티브 표현식, 콧수염 표현식에서도 사용이 가능해요.
얼핏 보기에 methods
옵션과 computed
옵션은 동일해보이는데 methods
옵션은 매번 함수를 계산을 하고 computed 옵션은 캐싱된 결과를 바로 리턴하는 것이 차이점이죠. 확실한 차이를 알고 싶으시면 computed
옵션에 설정한 함수에 console.log("test")
를 찍어보시면 알 수 있어요. computed 옵션은 로그를 출력하지 못하죠, 즉 이미 계산된 결과 값만 리턴이 되는 것이고 methods 옵션은 로그가 찍힐텐데 매번 함수에 있는 모든 줄을 실행한다는게 되겠죠?
그러면 이 차이가 왜 필요한지 생각해봐야해요. 지극히 개인적인 제 생각이지만 함수(단순연산이지만 매우 긴)를 겹겹히 호출을 한다고 보면 computed 옵션을 사용하면 아주 빠르게 값이 나올테지만 methods옵션을 사용시에는 시간이 아무래도 좀 걸릴거라 생각해요. 뭐 이런 용도의 차이로 사용하지 않을까해요.
watch 옵션
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
x: <input type="text" v-model="a"><br>
y: <input type="text" v-model="b"><br>
x*y : {{ sol }}
</div>
</body>
</html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
a : 0,
b : 0,
sol : 0
},
watch: {
a: function(v){
console.log("a변경");
var result = Number(v) * Number(this.b);
if(isNaN(result)) this.sol = 0;
else this.sol = result;
},
b: function(v){
console.log("b변경");
this.b = v;
var result = Number(this.a) * Number(v);
if( isNaN(result) ) this.sol = 0;
else this.sol = result;
}
}
});
</script>
감시용 옵션인 것 같아요. function의 매개변수로 전달되는 v 값은 앞의 a의 변수가 변경된 값이 되요. watch는 데이터 변경에 대한 응답으로 비동기시 또는 시간이 많이 소요되는 조작을 수행하려는 경우에 유용하게 사용되는데요. 생각해보면 당연한게 시간이 오래걸리거나 비동기로 처리하게되면 값이 나중에 바뀌죠. 그 시간동안 사용자가 뭘할지는 저희는 알 수가 없어요. 하지만 watch를 사용하면 값이 변경되는 순간 변경된 값을 체크해내서 값을 읽어들인다는 거죠. 비동기 처리에 관련된 예제도 한번 알아볼게요.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="watch-example">
<p>
yes/no 질문을 물어보세요:
<input v-model="question">
</p>
<p>{{ answer }}</p>
</div>
</body>
<script src="https://unpkg.com/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://unpkg.com/lodash@4.13.1/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<script>
var watchExampleVM = new Vue({
el: '#watch-example',
data: {
question: '',
answer: '질문을 하기 전까지는 대답할 수 없습니다.'
},
watch: {
// 질문이 변경될 때 마다 이 기능이 실행됩니다.
question: function(newQuestion) {
this.answer = '입력을 기다리는 중...'
this.getAnswer()
}
},
methods: {
// _.debounce는 lodash가 제공하는 기능으로
// 특히 시간이 많이 소요되는 작업을 실행할 수 있는 빈도를 제한합니다.
// 이 경우, 우리는 yesno.wtf/api 에 액세스 하는 빈도를 제한하고,
// 사용자가 ajax요청을 하기 전에 타이핑을 완전히 마칠 때까지 기다리길 바랍니다.
getAnswer: _.debounce(
function() {
if (this.question.indexOf('?') === -1) {
this.answer = '질문에는 일반적으로 물음표가 포함 됩니다. ;-)'
return
}
this.answer = '생각중...'
var vm = this
axios.get('https://yesno.wtf/api')
.then(function(response) {
vm.answer = _.capitalize(response.data.answer)
})
.catch(function(error) {
vm.answer = '에러! API 요청에 오류가 있습니다. ' + error
})
},
// 사용자가 입력을 기다리는 시간(밀리세컨드).
500
)
}
})
</script>
</html>
https://kr.vuejs.org/v2/guide/computed.html에 나와있는 예제인데요. watch 옵션에 비동기 혹은 시간이 오래걸리는 method를 사용해놓으면 되는거죠. angular랑 다르게 vue는 api콜하는부분과 api콜하는동안의 부분이 명확하게 구분되어 있는게 좋은 것 같네요. angular에서는 하나로 합쳐서 처리했었는데... 확실히 보기가 편하네요.
추가적으로 _.debounce() 함수는 일정시간이 지나도록 연속적인 호출이 일어나지 않으면 실제 API를 호출하는 용도로 사용한거에요. 연속적으로 타이핑하다가 0.5초동안 타이핑이 일어나지 않으면 api호출이 되므로 불필요한 api호출을 줄일 수 있겠네요.
v-cloak
이 예제에서는 {{answer}}가 보일일이 없지만 만약에 api호출로 test라는 데이터를 받아오고 받고나서 그 중에 name이라는 데이터를 뿌리는 거라면 {{test.name}} 이런식으로 표현이 되겠죠? 컴퓨터 상태에 따라 다르겠지만 이런 경우 test.name이 변경되기 직전에(컴파일하는동안) 콧수염이 보일수 있단말이에요. 이 때 사용하는게 v-cloak이라고 말씀드렸는데. 구체적인 사용방법을 알려드릴게요.
해당 vue인스턴스가 적용된 엘리먼트의 속성에 v-cloak을 추가하시면되요.div id="watch-example" v-cloak
그리고 style을 바꾸는 부분에서[v-cloak] { display: none; }
을 추가해주시면 v-cloak이 적용이 되요.
Vue 인스턴스 라이프 사이클
어떤 프레임워크를 배우든 라이프 사이클은 굉장히 중요하다고 생각해요. 왜냐하면 코드를 엄청 줄일 수 있는 신기한 기능들을 많이 탑재하고 있거든요. angular의 경우 ngDoCheck() 같이 모든 속성의 변화를 감지하는 메소드들 처럼요. 딱히 저희가 구현하지 않아도 여러가지 기능이 탑재되어 있어요.
지금 당장은 거의 사용할일이 없지만 컴포넌트를 만들고 관리를 할 때는 반드시 사용하게 될테니 알아는 둬야겠죠.
- beforeCreate : Vue 인스턴스가 생성되고 데이터에 관한 관찰 기능 및 이벤트 감시자 설정 전에 호출
- create : Vue 인스턴가 생성된 후에 데이터에 대한 관찰, 계산형 속성, 메서드, 감시자 설정이 완료된 후 호출
- befoeMount : 마운트가 시작되기 전에 호출
- mounted : el에 vue 인스턴스의 데이터가 마운트된 후에 호출
- beforeUpdate : 렌더링,패치 전에 데이터가 변경될 때 호출
- updated : 데이터의 변경으로 다시 렌더링되고 패치 된 후에 호출
- beforeDestroy : Vue인스턴스가 제거되기 전 호출
- destroyed : Vue 인스턴스가 제거되고 나서 호출 // 디렉티브 바인딩, 이벤트 해제 및 제거
딱 봐도 저는 mounted 나 updated는 많이 쓰일 것 같은 감이오네요. (updated는 진짜 많이쓰이겠다ㅋ)
'Front_End > Vue.js' 카테고리의 다른 글
05. Vue.js Dynamic CSS 적용하기 (0) | 2018.12.14 |
---|---|
04. Vue.js 스타일 적용 방법 (0) | 2017.12.26 |
03. Vue.js 초간단 Event Handling (1) | 2017.12.25 |
01. Vue.js 기본기: 각종 디렉티브 (0) | 2017.12.23 |
00. Vue.js 설치와 시작 (2) | 2017.12.22 |