2 vue.js 소개
source: categories/study/vue-beginner-lv1/vue-beginner2.md
2.1 MVVM 모델에서의 Vue
vue는 mvvm 패턴의 뷰모델 레이어에 해당하는 화면단 라이브러리라고 되어있습니다.
위에 보시는 이미지가 vue 공식문서에 나와있는 그림입니다.
위 그림에서 왼쪽에 View라는 것은 브라우저에서 사용자에게 비춰주는 화면을 의미합니다. 따라서 화면의 입력박스라던지 버튼이라던지 그런 것들이 view에 해당하겠죠.
화면에 나타나는 요소들, 저희가 흔히 알고있는 html, 그 html은 DOM이라는 것들을 이용해서 자바스크립트로 조작을 할 수 있게끔 구성이 되어집니다.
view에서 특정 사용자가 키보드를 입력한다던지 마우스를 클릭했을 때, Vue에서 Dom Listener로 해당 입력을 듣게됩니다.
vue에서 그런 event를 잡아서 자바스크립트에 있는 데이터(model)를 바꿔주거나 혹은 자바스크립트에서 지정한 특정 로직에서 실행을 하게됩니다.
이게바로 vue에서 갖고있는 큰 2가지 특징 중에 하나인 DOM Listener라고 보시면된다.
자바스크립트의 데이터가 변했을 때 Data Bindings를 하게되는데, 자바스크립트의 데이터 중에 어떤 문자가 바뀌었다, 혹은 숫자가 바뀌었다고 했을 때 그런 내용들을 Data Bindings를 통해서 바로 화면에 반영하게된다.
위와 같은 것들이 코드상 실제로 어떻게 동작하는지 살펴보도록 하겠다.
2.2 기존 웹 개발 방식(HTML, Javascript)
앞시간에 살펴본 위 그림을 좀 더 잘 이해하기 위해서 코드를 작성해보도록 하겠다.
일반 웹 개발 방식을 보기위해 web-dev.html 파일을 하나 생성합니다.
일반적으로 지금 나와있는 angular, react, vue와 같은 프레임워크를 쓰지않고 웹을 개발한다고 하면, html, css, javascript를 활용할 수 있습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script>
var div = document.querySelector('#app');
console.log(div);
</script>
</body>
</html>
위와 같이 코드를 작성하면 브라우저의 콘솔창에서 해당 div 값을 확인할 수 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script>
var div = document.querySelector('#app');
console.log(div);
div.innerHTML = 'hello world';
</script>
</body>
</html>
보통 위와 같이 값들은 변수(str
)에 담고 그 변수를 div.innerHTML = str;
이런식으로 할당하는 식으로 구현한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script>
var div = document.querySelector('#app');
var str = 'hello world';
div.innerHTML = str;
str = 'hello world!!!';
</script>
</body>
</html>
그랬을 때 위와 같이 str
의 값이 hello world!!!
로 바뀐다면,
저장하시고 다시 화면을 보시더라도 바뀐 내용이 화면에 반영되지 않습니다.
hello world!!!
가 화면에 반영되질 않죠.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script>
var div = document.querySelector('#app');
var str = 'hello world';
div.innerHTML = str;
str = 'hello world!!!';
div.innerHTML = str;
</script>
</body>
</html>
그럴때마다 저희는 해당 div
에 innerHTML
에 다시한번 str
을 할당해서 마지막으로 갱신된 값을 브라우저 화면에 표시했습니다.
이것이 일반적인 웹개발 방식, html, css, javascript로 개발하는 방식이었습니다.
다음시간엔 이런식의 개발방식을 어떻게 vue.js로 쉽게 접근할 수 있는지 보여드리겠습니다.
2.3 Reactivity 구현
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script>
var div = document.querySelector('#app');
var str = 'hello world';
div.innerHTML = str;
str = 'hello world!!!';
div.innerHTML = str;
</script>
</body>
</html>
기존 웹개발 방식.
위와 같이 str 값이 바뀔 때마다 할당 코드를 다시 작성해 값을 바꿔주는 방식.
이를 vue.js의 핵심 사상인 reactivity를 사용하면 어떤점이 편해지는지 볼게요.
vue-way.html 파일을 새로 만들자.
이제 vue의 reactivity를 살펴보도록 하겠습니다.
Object.defineProperty();
라는 API
를 사용해볼게요.
Object.defineProperty();
라고 하는 것은 객체의 동작을 재정의하는 API
라고 보면된다.
위와 같이 간단한 것에 대해 모르는 분은 없을겁니다.
a라는 변수에 10을 할당한 것이죠. a를 찍어보면 10이라는 값이 출력됩니다.
그리고 a라는 변수에 20이라는 값을 재할당할 수도 있습니다.
Object.defineProperty();
는 특정 객체의 속성의 동작에 대해 정의합니다.
객체의 속성이 어떻게 동작하는지에 대해 저희가 정의할 수 있다는 겁니다.
- 첫번째 인자: 대상 객체
- 두번째 인자: 객체의 프로퍼티 키
- 세번째 인자: 해당 프로퍼티 키의 값 및 기타 옵션들..(객체형태로 넘여야됨)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script>
var div = document.querySelector('#app');
var viewModel = {};
// Object.defineProperty() 메소드는 특정 객체의 속성의 동작을 정의하는 API라고 보면됩니다.
// Object.definedProperty(대상객체, 객체의속성, {
// // 정의할 내용
// })
Object.defineProperty(viewModel, 'str', {
// 속성에 접근했을 때의 동작을 정의
get: function () {
console.log('접근');
},
// 속성에 값을 할당했을 때의 동작을 정의
set: function (newValue) {
console.log('할당', newValue);
}
});
</script>
</body>
</html>
이러한 API
를 활용해서 str
프로퍼티 키에 담긴 value가 바뀌면 계속해서 화면에 뿌려줘라 라고 만들 수 있습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script>
var div = document.querySelector('#app');
var viewModel = {};
// Object.defineProperty() 메소드는 특정 객체의 속성의 동작을 정의하는 API라고 보면됩니다.
// Object.definedProperty(대상객체, 객체의속성, {
// // 정의할 내용
// })
Object.defineProperty(viewModel, 'str', {
// 속성에 접근했을 때의 동작을 정의
get: function () {
console.log('접근');
},
// 속성에 값을 할당했을 때의 동작을 정의
set: function (newValue) {
console.log('할당', newValue);
div.innerHTML = newValue;
}
});
</script>
</body>
</html>
위와 같이 newValue
, 즉 새로운 값을 받을 때마다 div.innerHTML = newValue;
코드로 새로운 값을 넣어준다면, 화면이 값이 갱신될 때마다 계속해서 바뀔겁니다.
위와 같이 값이 바뀔 때마다 화면에 계속해서 새로운 값을 뿌려주게됩니다.
이것이 바로 vue의 핵심인 reactivity라는 것이고, 한글로 표현하면 반응성이라고 하면 될 거 같습니다.
vue의 핵심은 데이터의 변화를 라이브러리에서 감지해서 알아서 화면에 그려주는 것!!!! 바로 reactivity라고 보시면 될 것 같다.
이러한 것들을 data bindings라고 보면된다.
다음시간엔 이러한 vue.js의 reactivity를 라이브러리 비슷한 느낌으로 만들어보겠습니다.
위 코드를 어떻게 라이브러리화 할 수 있는지..
2.4 Reactivity 코드 라이브러리화 하기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script>
var div = document.querySelector('#app');
var viewModel = {};
// Object.defineProperty() 메소드는 특정 객체의 속성의 동작을 정의하는 API라고 보면됩니다.
// Object.definedProperty(대상객체, 객체의속성, {
// // 정의할 내용
// })
Object.defineProperty(viewModel, 'str', {
// 속성에 접근했을 때의 동작을 정의
get: function () {
console.log('접근');
},
// 속성에 값을 할당했을 때의 동작을 정의
set: function (newValue) {
console.log('할당', newValue);
div.innerHTML = newValue;
}
});
</script>
</body>
</html>
위 코드를 라이브러리화 해보겠습니다.
위와 같이 Object.defineProperty()
코드를 그대로 function init(){}
함수 안으로 넣어줍니다.
위 코드에서 set 함수에 있는 div.innerHTML = newValue;
코드를 render
라는 함수로 옯겨보겠습니다.
위와 같이 코드를 수정해줍니다.
function render(){}
함수를 만들고 set
함수에서 render
함수를 호출하도록.
그리고나서 위 함수를
이런식으로 init();
호출할 수 있다.
최종적으로 하실일은 즉시실행함수라는 자바스크립트 기법이 있습니다.
즉시실행 함수 안에 아까 작성한 코드들을 전부 넣습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script>
var div = document.querySelector('#app');
var viewModel = {};
// Object.defineProperty() 메소드는 특정 객체의 속성의 동작을 정의하는 API라고 보면됩니다.
// Object.definedProperty(대상객체, 객체의속성, {
// // 정의할 내용
// })
(function () {
function init () {
Object.defineProperty(viewModel, 'str', {
// 속성에 접근했을 때의 동작을 정의
get: function () {
console.log('접근');
},
// 속성에 값을 할당했을 때의 동작을 정의
set: function (newValue) {
console.log('할당', newValue);
render(newValue);
}
});
}
function render (value) {
div.innerHTML = value;
}
init();
})()
</script>
</body>
</html>
즉시실행함수가 하는 역할.
init()과 render()함수가 어플리케이션에 노출되지않게하기 위함. 노출되지 않게하기위해 또다른 scope에 넣어주는 것.
일반적으로 오픈소스 라이브러리들은 이런식으로 변수의 유효범위를 관리하고 있다.
위와 같이 제대로 동작하는 걸 볼 수 있다.
이런식으로 간단한 reactivity를 간단한 라이브러리화까지 해봤는데, 아마 지금 배우신 내용들로 프레임워크를 학습하실 때 더 많은 기반을 닦아나갈 수 있으실겁니다.
2.5 Hello Vue.js와 뷰 개발자 도구
Vue로 Hello World를 찍어보는 것을 해보겠습니다.
getting-started 폴더에서 index.html을 열어보시면 위와 같이 script 태그로 cdn에 vue.js 파일을 들고와서 vue를 돌려보는 코드를 작성했습니다.
저장하시고 live server를 실행해보면
vue 개발자 도구.
vue 개발자도구는 components, vuex, events 등등 여러가지 기능들을 제공한다.
저희가 지금 보고있는 것은 components 탭이고 components는 기본적으로 vue.js를 실행하셨을 때, component 구조를 보여줍니다.
지금 저희는 인스턴스 하나를 등록했고 실행했기 때문에 Root라는게 나왔고 이건 다음 시간에 좀 더 자세하게 설명드릴게요.
data에 message라는게 나와있습니다.
이게 바로 vue에서 관리하는 data인데,
이 값을 위와 같이 바꿔보겠습니다.
그럼 위와 같이 화면이 바뀌는 것을 볼 수 있습니다.
또 위와 같이 바꿔도 바로 바뀌는걸 볼 수 있습니다.
그대로 모든 것이 바로바로 반영됩니다.
저희가 이전 시간에 구현했었던 reactivity, 그게 vue의 data 속성에 모두 반영이 되어있기 때문에, data의 변화에따라 화면에 바로바로 자동으로 그려지는 것입니다. 그것이 바로 reactivity입니다.
위 코드의 상세 설명들에 대해선 다음 시간부터 이어서 보도록 하겠습니다.
다음 첫시간에 배울 것은 인스턴스인데,
지금 위에서 보시는 new Vue()
에 대해서 저희가 한번 알아보도록 하겠습니다.