Vue - 인스턴스!
vue 인스턴스 옵션
vue 인스턴스
에서 여러가지 옵션객체
, 옵션메서드
를 제공하는데
데이터 바인딩, 이벤트 핸들링 등에서 필수로 알아야할 옵션을 알아본다.
new Vue ({
// 옵션 객체
data: { name: "Editor" },
// 옵션 메서드
computed: {
merge_name: function() {
return "Lee Joong-Min"
}
},
watch: {
name: function (new_value, old_value) {
// TODO data changed
}
}
});
vue 인스턴스
옵션을 통해 vue 템플릿
에 데이터 바인딩할 뿐 아니라
이벤트 핸들링, 라이프사이클에 따른 후킹작업등을 수행하는데
이런 작업을 총망라해서 부트스트래핑(Bootstrapping) 이라 한다.
el
vue 인스턴스
가 동작할 DOM 요소
를 지정할 때 사용
CSS 선택자
를 사용하며 최대한 작은 범위를 선택하는 것을 권장한다.
<div id="test">
{{name}}
</div>
<script>
var vinstance = new Vue({
el: "#test",
data: { name: "홍길동" }
})
</script>
DOM 요소
와 vue 인스턴스
연결을 el
객체로 연결하였는데 다중 연결은 지원하지 않는다,
CSS 선택자
를 통해 검색된 첫번째 요소에만 연결처리된다.
실행 도중 동적으로 DOM 요소
와 vue 인스턴스
연결은 가능하나 이미 연결된 관계를 변경할 수는 없다.
data
vue 컴포넌트
의 상태값이라 부르기도 하며 데이터 바인딩시 사용
<div id="test">
{{name}}
</div>
<script>
var vinstance = new Vue({
el: "#test",
data: { name: "홍길동" }
})
</script>
#simple
아이디값을 가진 DOM 객체에서
div
태그 사이에 홍길동이 출력된다.
스크립트 내부에서 name
에 접근하는 방법들을 알아보자.
vinstance.name
vinstance.$data.name
vue인스턴스
와data옵션객체
사이에 프록시($data
)를 두어 처리,
data
옵션객체를 변경사항이 발생되면 즉시 감지되어 이벤트처리된다.
vinstance.name
과vinstance.$data.name
의 차이점을 보면 프록시객체에 접근방법도 알 수 있다, 앞에$
를 붙이면 된다.
template
html markup
을 바인딩할 때 사용
다음과 같이 template
에 html 마크업을 지정하면
자식 요소를 template
의 html 마크업으로 교체한다.
var vm = new Vue({
el: "div#markup",
template: "<h2>{{ markup }}</h2>",
data: { markup: "새로운 마크업" }
});
template 으로 사용할 markup 이 복잡하다면 별도의 script 태그로 분리해서 사용할 수 있다.
<script type="text/x-template" id="markup_tmplp">
<p>Hello, {{ name }}</p>
</script>
<script>
var vm = new Vue({
data: { name: "Hanbit" },
template: "#markup_tmpl"
});
</script>
parent
상위 vue 컴포넌트
를 설정할 때 사용
잘 사용하지 않고 단순 독립 컴포넌트 형태로 사용하는 경우가 많음
var parent_vm = new Vue({ });
var child_vm = new Vue({ parent: parent_vm });
parent_vm
의 $children
배열에 child_vm
가 포함되며
child_vm
의 $parent
속성에 parent_vm
가 할당된다.
mixin
mixin
옵션을 사용해 객체를 사용해 vue 컴포넌트
들의 옵션을 표현할 수 있다.
vue 컴포넌트
를 여러개에 동일한 옵션들을 삽입해야할 때 사용한다.
mixin
의 옵션들은 기존 vue 컴포넌트
에서 정의한 옵션들과 겹칠 수 있다.
또한 mixin
은 옵션배열로 mixin
객체들 사이에서 중복되는 옵션들이 정의될 수 있다.
vue 에선 우선순위를 지정하여 mixin 옵션에 우선권을 차례대로 부여하며
vue 컴포넌트
에서 정의한 옵션은 최후에 사용된다.
computed
인스턴스 템플릿
에 함수결과를 표시하려면 Mustache
표현식을 사용해도 되지만
랜더링시에 포현식이 실행되어 성능하락을 야기한다.
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
랜더링 전에 미리 계산된 속성으로 사용하는 방법을 권장한다.
computed
속성은 반드시 인자를 받지 않는 함수로 구성해야 한다.
<div id="example">
{{ reversedMessage }}
</div>
<script>
new Vue({
el: '#example',
data: { message: 'Hello Vue.JS World' }
computed: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
});
</script>
computed
속성값을 인스턴스 내부에 저장해두는 캐싱방법을 사용하기에
캐시가 초기화 되지 않는 이상 재랜더링 되더라도 동일한 데이터가 출력된다.
캐시 초기화 조건은
data
가 업데이트 되었을 때
아래처럼 getter
, setter
를 정의해서 사용하는 것도 좋은 방법
computed
의 읽기만 한다는 틀을 깨고 setter
을 통해 값을 초기화 하는 것도 가능하다.
computed: {
fullName: {
get: function () {
return this.firstName + ' ' + this.lastName
},
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
methods
watch
vue 인스턴스
의 상태값 변경을 감시하는 옵션
vue 인스턴스
에서 변경이 일어나면 호출하는 computed
의 메서드와 달리
watch
속성은 긴 시간동안 해당 데이터의 변경이 일어나는지 관찰하며 특정 메서드를 호출하여 비동기 처리에 적합하다.
또한 함수의 반환값을 지정할 필요도 없다.
<div id="example">
x: <input type="text" v-model="x" /><br>
y: <input type="text" v-model="y" /><br>
덧셈결과: {{sum}}
</div>
<script>
var vm = new Vue({
el: "#example",
data: { x: 0, y: 0, sum: 0 },
// 옵션객체
watch: {
// function (newVal, oldVal) 이전의 데이터도 사용 가능
x: function (v) {
console.log("## x 변경, v:" + v);
var result = Number(v) + Number(this.y)
if (isNaN(result)) this.sum = 0;
else this.sum = result;
},
y: function (v) {
console.log("## y 변경, v:" + v);
this.y = v;
var result = Number(this.x) + Number(v)
if (isNaN(result)) this.sum = 0;
else this.sum = result;
}
}
})
</script>
watch
옵션에 immediate
, deep
속성을 추가로 정의할 수 있다.
deep: true
일 경우 내부 객체의 변화까지 감시한다.
immediate: true
일 경우 초기화와 동시에 watch 의 핸들러 함수가 호출된다.
watch: {
b: {
handler: function (val, oldVal) {
console.log(val); // 4
console.log(oldVal); // undefiend
},
deep: true, //default false
immediate: true // default false
}
}
deep
을 사용하지 않고 객체 속성의 변화까지 추적하고 싶다면 아래와 같이 속성명을 사용
watch: {
'a.b': function (new_val, old_val) {
console.log(new_val);
console.log(old_val);
},
}
computed, methods, watch 차이
값을 연산해 반환하는 메서드를 호출하고 computed
혹은 methods
속성을 사용한다.
<body>
<div id="example">
<input type="text" name="" id="" v-model="num"><br>
1 부터 입력된 수까지의 합:
<br>
{{sumMethod()}}
{{sumMethod()}}
<br>
{{sumCompute}}
{{sumCompute}}
</div>
<script>
var vsum = new Vue({
el: "#example",
data: {
num: 10
},
methods: {
sumMethod: function () {
console.log("sumMethod:" + Date.now());
var n = Number(this.num);
if (Number.isNaN(n) || n < 1) return 0;
else return (1 + n) * n / 2;
}
},
computed: {
sumCompute: function () {
console.log("sumCompute:" + Date.now());
var n = Number(this.num);
if (Number.isNaN(n) || n < 1) return 0;
else return (1 + n) * n / 2;
}
}
})
</script>
</body>
사용방법만 놓고 보면 둘의 차이점은 매우 미비하나 내부 동작방식의 차이점이 있다.
computed
의 경우 data
값의 변경 여부에 따라
캐싱된 값을 return
할지, 메서드를 호출해 연산값을 return
할지 결정한다.
methods
의 경우 항상 메서드 연산을 통해 값을 return
한다.
코드상에선 두 속성을 2번씩 호출하지만 computed
의 경우 그중 한번은 캐시값을 반환함으로 console
에 한번만 출력된다.
computed
, watch
모두 vue 인스턴스
내부의 연관된 data
가 변경되면 호출된다.
만약 아래와 같이 연관된 data
값이 없을경우 computed
메서드는 한번도 호출되지 않는다.
computed: {
sumCompute: function () {
console.log("sumCompute:" + Date.now());
}
},
watch: {
sumWatch: {
console.log("sumWatch:" + Date.now());
}
},
computed
와 watch
사용방법은 여러가지 차이가 있다
computed
의 경우 연관 data
를 한 메서드에서 다중 설정 가능하지만 watch
는 하나의 변수만 감시할 수 있다.
사용 방법또만 computed
에 정의된 메서드를 호출하려면 콧수염 방식으로 호출해야 하는 반면 watch
의 경우 콜백형식으로 호출된다.
vue 필터
데이터 바인딩하여 랜더링 하기 전
전후처리를 통해 데이터를 변경해야 할 때 필터를 사용하면 좋다.
전역필터
와 컴포넌트 한정필터
가 존재하며
vue 인스턴스
선택자에 따라 지정하면 된다.
필터의 첫번째 매개변수는 파이프라인으로부터 넘어온 값이 사용되며
매개변수를 아래처럼 별도로 지정 가능하다.
파이프를 이어 여러번 필터를 거치게 할 수 있다.
<div id="app">
<span>{{ i | multiply_number1 }}</span><!-- 10 출력 -->
<span v-text="i | multiply_number2(3)"></span><!-- 15 출력 -->
</div>
<script>
/* 전역필터 */
Vue.filter('multiply_number1', function (value) {
return value * 2;
});
var app = new Vue({
el: '#app',
data: { i: 5 }
/* 컴포넌트 한정필터 */
filters: {
multiply_number2: function (value, number) {
return value * number;
}
}
});
</script>
아래와 같은 필터를 자주 사용한다.
var app = new Vue({
filters: {
/* 첫문자 대문자 */
capitalize: function (text) {
return text[0].toUpperCase() + text.slice(1)
},
uppercase: function (text) {
return text.toUpperCase()
},
lowercase: function (text) {
return text.toLowerCase()
}
}
});
vue 인스턴스 속성
이미 생성된 vue 인스턴스
의 옵션을 참조하고 싶다면 아래와 같이 $...
키워드를 통해 접근 가능하다.
vue 인스턴스
가 각 옵션에 접근전에 한 단계의 관문(프록시) 를 생성했기 때문
vm.$data
:data 옵션
참조vm.$props
: data옵션vm.$el
: data옵션vm.$options
: data옵션vm.$root
: data옵션vm.$parents
: data옵션vm.$children
: data옵션vm.$slots
: data옵션vm.$scopedSlots
: data옵션vm.$refs
: data옵션vm.$isServer
: data옵션