티스토리 뷰
0. 들어가면서
Vue를 처음 배우는 사람이라면 바로 이곳에서 시작해 보길 바란다. 전반적인 개념과 시작하는 방법이 적혀있다. 자바스크립트를 모르더라도 어느정도 구현할 수 있도록 노력했다.
일단 frontend와 backend의 차이를 모르는 사람도 있을 것이다. 매우 쉽게 설명을 하자면, frontend는 컴퓨터의 모니터 부분이라고 생각을 하고, backend부분은 컴퓨터의 본채라고 생각하면 된다. 즉, frontend부분은 사용자가 실제로 볼 수 있는 부분이고, 다른 DB처리라던가 복잡한 알고리즘은 backend에서 한다고 생각하면 된다. 우리가 배울 Vue는 바로 frontend 부분이라고 생각하면 된다.
여기서는 Vue의 기초를 다룬다. Vue Cli로 바로 알고 싶다면 아래의 링크를 클릭하자.
여기서는 시작하는 법과 필요 문법을 배운 뒤에 아래와 같은 순서로 배울 것이다.
2020/11/17 - [Web/Vue.js] - [Vue.js] 2. 데이터 받기(get)
2020/11/20 - [Web/Vue.js] - [Vue.js] 3. lifecycle hook 적용하기
2020/12/05 - [Web/Vue.js] - [Vue.js] 4. scrollmonitor(무한스크롤) 적용하기
2020/12/07 - [Web/Vue.js] - [Vue.js] 5. computed 기초 정리
2020/12/08 - [Web/Vue.js] - Vue CLI 기초 정리
2020/12/15 - [Web/Vue.js] - Vue 배포 기초
2020/12/17 - [Web/Vue.js] - Vue Cli router 기초 정리
0.1 front-end 프레임워크 종류
- Angular
- React
- Vue
뷰가 가장 생긴지 얼마 안되었다. 그래서 앵귤러와 리액트의 장정을 뷰가 가졌다고 할 수 있다. 그렇다고 Vue가 Angular와 React 보다 반드시 좋다고는 할 수 없다. 현재, angular의 점유가 줄어드는 추세고, Vue와 React가 선두를 다투고 있는 중이다. 나는 그나마 배우기 쉬운 Vue.js를 적어보도록 하겠다.
Vue.js는 Evan You이 개발하셨다. 구글 입사 후에 Angular를 썼는데, 가벼운 작업도 angular는 무겁게 작동하길래 줄이다보니 Vue.js를 만들었다.
1.Vue.js 개념
Vue는 사용자 인터페이스를 위한 Front-End에 적용할 수 있는 프레임워크이다.
1.1 Vue 특징
1. front-end(client-side)
사용자와 브러우저간의 소통할 수 있는 도구
2. SPA(Single Page Application)
기존의 웹은 요청할때마다 그에 대한 응답을 문서(html)로 받음. 작은 변화만 있어도 리소스전체를 받아야한다.
UX(사용자경험)가 떨어져서 사용자가 보기 힘들다. 리소스 전체가 새롭게되므로 시간, 메모리적 손해는 필수적이다.
Vue를 이용하여 처음에만 큰 문서 한장을 받고, 페이지를 리로드 없이 비동기요청을 통해 JSON(key value형식)만을 주고 받는다. (단점은 큰 문서를 처음에 한장 받는데 시간이 걸린다.)
즉, 전체가 아닌 각각의 부분별로 비동기요청(각각의 HTML CSS JS)을 한다. 그래서 비동기 요청을 하기위해 JS를 쓴다.
3. Client Side Rendering
기존) 서버에서 html을 만들고 완성시켜 던지면, client가 받는다. 따라서 용량이 컸다.
현재) client Side Rendering-서버가 던진 문자열을 브라우저가 받아서 만든다. 이때 브라우저가 일을 하려면 JS가 필요하다.
즉, 서버가 문서(자바스크립트뭉치)던지면, 브라우져가 해석을 한다.(옛날에는 다 완성해서 client에게 던짐)
4. MVVM패턴(Model View ViewModel)
Model(M) : Object = Key, Value
View(V) : HTML
ViewModel(VM) : model과 view를 연결하는 역할을 한다.(vue부분)
즉, Object와 HTML의 중개자가 Vue
5. 반응형(Reactive)/선언형(Declarative)
React가 해결하고자 하는 문제는 Vue와 비슷하다. 지향점이 비슷하다.
원래는 하나하나 전부 다 코드 적어서 넣었는데, {{ }}을 이용해서 for문에 반복 하게 만들어서, 하나씩 코드를 안적어도 전체적으로 반응하게 한다.
반응형)뷰모델(data)이 바뀌면 뷰(DOM)도 바뀐다.
2. Vue를 쓰는 이유
사실 HTML로 하나씩 만들어도 된다. 그러나 Vue를 쓰는 이유가 있기 때문에 Vue를 쓸 것 이라고 생각한다. 즉, Vue를 쓰는 이유를 짧게 정리해 보면 아래와 같다.
- 배우기 쉽다
- 돈이 덜든다
- UX향상 - 비동기 요청을 하면 이어지게되어 웹페이지에 몰두한다
- 프레임워크의 장점
- 유지보수가 용이하다
- 충분한 라이브러리와 커뮤니티가 존재한다
3. Vue 시작
3.1 Vue 환경설정
기본적으로 Visual Studio code가 설치되어 있다고 가정하고 시작해 보겠다.
Visual Stdio Code에서 extentions 설치하자. vetur 검색 후 설치 - Vue tooling for VS code이다.
구글검색) Vue chrome extension - 들어가서 vue.js devtools를 크롬에 추가
그러면 브라우저 상측 url 오른쪽에 새로운 모양이 버튼이 생길 것이다.
우클릭해서 들어가서 확장프로그램관리 클릭
파일 URL에 대한 엑서스허용을 꼭 켜주자.
위의 부분을 꼭 켜줘야 진행하면서 사용가능하다.
2.3 Vue의 CDN 적용
CDN이란, Vue를 따로 설치하지 않고, html에 한줄을 추가하면 사용할 수 있게 만들어주는 것이라고 생각하면 된다.
구글에 다음을 검색해 보자. Vue js CDN
- 그리고 공식문서에 들어가서 '설치방법' 보자.
kr.vuejs.org/v2/guide/installation.html
공식 문서를 보니 두가지의 CDN을 제공한다.
(공부 시에는 CDN을 사용하고 프로젝트를 진행한다면 다운받으면 된다.)
개발버전(우리는 이걸 사용)
프로토 타이핑또는 학습 목적이라면, 아래 코드로 최신 버전을 사용할 수 있습니다.
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
프로덕션 환경인 경우 새 버전에서 예상치 못한 오류를 방지하려면 특정 버전의 빌드 파일을 추가하는것을 추천합니다.(상용버전)
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
2.4 코드 작성
visual studio code를 열어서 오른쪽 마우스를 클릭하고 new file을 누르고 아래와 같이 html 파일을 하나 만들어준다. 이때, 이름과 위치는 크게 상관이 없고, html 하나만 만들어 주면 된다.
그리고 app.html을 더블클릭해서 들어간 후에 !를 치고 tab을 누르면 자동으로 html 파일이 자동완성되는 것을 볼 수 있다. 그리고 아래와 같이 쳐주자.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue Tutorial</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
})
</script>
</body>
</html>
위의 코드가 장고의 startproject 했던 것과 같다고 보면 된다. 다른말로는 Vue를 시작할 준비가 된것이다. 나는 아래와 같이 작성을 해보았다.
2.5 코드 해석
아래의 내용이 이해가 안된도 된다. 그렇구나 하고 넘어가자. 하다보면 이해가 자연스럽게 될 것이다.
body
하나의 뷰 모델, 하나의 인스턴스 라고 하는 것은 하나의 부모 요소를 잡아야 한다. 쉽게 말해서 위의 body 안에 div tag 를 넣어주고 그 안에 다른 태그를 넣는 방식으로 하자. 즉, div tag 하나 적어놓고 시작하자. <div id="app">을 반드시 적어 줘야 Vue가 마운트 할 요소를 찾을수 있다.
body/script
뷰는 속성과 디렉티브를 둘다 알아야 한다.
const app = new Vue({
})
만 적으면 아무일이 일어나지 않는다. 안에 인자로 object(객체)를 넣어 줘야 한다.
안에 중괄로는 오브젝트가 나열되어 있는것이기 때문에 꼭 적어주는 것이 필요하고, 인자를 추가할 때 마다 반드시 ,(콤마)를 넣어서 인자들을 분리해 줘야한다.
지금부터 중괄로 안에 있는 인자들을 속성 이라고 부를거다.
const app 추가 설명
혹여나 왜 아래 처럼 적어야 하는가에 대한 의문은 가지지말자. 만든사람 마음이기 때문에 받아들이면 된다.
<script>
// el은 Vue 인스턴스의 속성이다.
const app = new Vue({
el: '#app', // django의 startproject 느낌
data : { // object. MVVM에서 Model을 의미한다.
message: 'Hello Vue'
}
})
</script>
- el : el은 Vue 인스턴스의 속성이다. 어떤 요소에 mount(연동한다는 느낌으로 이해하자) 할지를 결정한다. mount 안하면 잡히는게 없어서 아무일도 일어나지 않는다. el 뒤에 잡을 element를적어준다. el의 #app이 위에 적은 div의 id인 app과 연결되어 연동이 일어난다. 따라서 가장 먼저 적게 될거다.
- data: 데이터라는 속성은 객체(object)다. MVVM에서 모델을 의미한다. Vue의 핵심이다. 데이터가 바뀜에 반응한다. 내부에 key value 형식으로 넣어주면 사용이 가능하다.
+위의 message에 console로 접근을 하려면, data.message가 아니라 app.message로 접근해야한다. 왜냐하면 내부적으로 자동으로 정렬 되기 때문에 data라는 것은 단지 형식일 뿐 따로 적을 필요는 없다.
처음 보면 무슨말인지 모르는게 당연하다. 하다보면 흐름이 이해가 될 것이다.
2.6 Vue 실행해보기
장고 extention을 하나 추가해보자
설치가 완료되면 아래와 같이 코드위에서 open in Default Browser를 눌러보자.
그리고 웹 열리면 F12 개발자 모드에 들어가서 Console을 들어가면 'Tou are running Vue in development mode.'라고 뜬다면, Vue가 실행 되고 있는거다.
이런식으로 창이 뜬다. 그리고 Vue를 누르자.
이런식으로 뜨면 뷰를 사용할 준비가 완료 된거다. 그렇다면 아래의 문법들을 따라 적어보면서 Vue의 흐름을 좀 더 디테일 하게 이해해 보자
3. 예제
아래의 실습 부터는 꼭 직접 처보면서 화면을 보면서 이해를 해보자.
3.1 보간법(interpolation) - {{ }}
{{ }} 이러한 기호는 자바스트립트와 html에 없는 처음 나오는 기호다.
<body>
<diV id="app">
{{ message }} //{{ }} html이랑 자바스크립트에 없던거..
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// el은 Vue 인스턴스의 속성이다.
const app = new Vue({
el: '#app', // django의 startproject 느낌
data : { // object. MVVM에서 Model을 의미한다.
message: 'Hello Vue'
}
})
</script>
보간법을 쓰려면 el에서 지정한 위치 안에서만 쓸수있다.
data. message가 아닌 {{ message }} 만으로도 부를 수 있다
JS였다면 타겟을 잡고 바꾸는 코드를 쳤어야하는데 여기서는 그런게 없다.
보간법은 html에 쓰려는 데이터를 바로 쓰게 해주는거구나.
만약 app으로 div 정의한 것 밖에서 {{ message }}를 쓰면 못 받아들인다. 일반 텍스트가 된다.
vue.js에서 한가지 일을 할 때 할 수 있는 방법이 굉장히 많다
결과는 다음과 같다.
3.2 v-text
v- 접두사로 시작하는 것들은 모두 디렉티브(vue 명령어) 라고 부른다.
<body>
<div id="app">
// Vanilla JS. domElement.innerText 와 같다.
<p v-text="message"></p>
<p>{{ message }}</p> // p태크 추가
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// el은 Vue 인스턴스의 속성이다.
const app = new Vue({
el: '#app',
data : {
message: '완전히 같아요'
}
})
</script>
보면 div안에 있는 2개의 p태그는 완전히 같다.
즉, Vue과 html과 연동이 되는 순간에 v- 라는 텍스트를 전부 모운 후에 html이 아닌 Vue에게만 연관되게 만든다. 예를들어 클래서를 class="message" 이렇게 지정하면 #message로 html에 연동이 되는데, 이것과는 완전 다르게 Vue에만 연관되어 작동할 수 있게 만드는 것이 v-라는 디렉티브이다.
v- 붙은 것들은 모두 디렉티브(명령)라고 부르고, data의 key랑 묶인다.
+ Vanilla JS.에서의 domElement.innerText와 완전히 같다.
3.3 v-if
<body>
<div id="app">
<p v-if="bool1"> //밑의 데이터랑 연결. 참이니가 true라고 뜬다.
true
</p>
<p v-if="bool2"> // false는 화면에 안뜬다
false
</p>
<p v-if="str1"> //밑의 데이터랑 연결. 참이니가 true라고 뜬다.
yes
</p>
<p v-if="str2"> // false는 화면에 안뜬다
''
</p>
<p v-if="num1"> //밑의 데이터랑 연결. 참이니가 true라고 뜬다.
1
</p>
<p v-if="nm2"> // false는 화면에 안뜬다
0
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// el은 Vue 인스턴스의 속성이다.
const app = new Vue({
el: '#app',
data : {
bool1: true,
bool2: false,
str1: 'Yes',
str2: '',
num1: 1,
num2: 0,
}
})
</script>
true
'Yes'
1
이라고 화면에 뜬다.(뷰가 참거짓을 판단하는게 아니고 자바스크립트의 true와 false의 판단과 같다.)
+ [], [1, 2]
+ {} {a : 1} if평가를 직접해보자
비어있는 배열 []와 빈 오브젝트 {} - true
그렇다면 비어있는 배열을 어떻게 false로 만들지? 배열 자체가 아니라 length로 판단한다.
<p> v-if="arr.length">로 판단한다. 0이면 false가 나오기 때문에 빈 배열은 false가 된다.
3.4 v-if else-if else
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='app'>
<p v-if="username==='master'">Hello Master</p>
<p v-else>Hello User</p>
<p v-if="number > 0">양수</p>
<p v-else-if="number < 0">음수</p>
<p v-else>0</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
username: 'master',
number: '0'
}
})
</script>
</body>
</html>
script의 username에 따라 출력 바뀜
number에 맞게 양수 음수 출력된다.
3.5 v-for
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='app'>
<ul>
<li v-for='number in numbers'>{{ number }}</li>
</ul>
<ol>
<li v-for='teacher in teachers'>{{ teachers.name }}</li>
</ol>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
numbers: [0, 1, 2, 3, 4],
teachers: [
{name: 'neo'},
{name: 'tak'}
]
}
})
</script>
</body>
</html>
- 0
- 1
- 2
- 3
- 4
- 5
- neo
- tak
라고 출력.
teachers는 배열이고 안에 요소는 object다. 따라서 teacher은 object다. 따라서 키값으로 value를 꺼내자(teach.nme)
{{ number + 1 }} 하면 1부터 ul이 뜬다. (자바스크립트로 인지한다)
3.6 v-bind: - 매우많이 쓴다.
표준 HTML 속성과 Vue 인스턴스를 연동할 때 쓴다. (v-bind:)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='app'>
<a v-bind:href="googleUrl">구글</a>
<a :href="naverUrl">네이버</a>
<img v-bind:src="randomImageUrl" alt="altText">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
googleUrl: 'https://google.com',
naverUrl: 'https://naver.com',
randomImageUrl: 'https://picsum.photos/200',
altText: 'random-image'
}
})
</script>
</body>
</html>
o <a href=""></a> 여기다가 먼가를 하고 싶다. "" 여기 사이에 위에서 배운 것 처럼 {{ googleUrl }}을 넣으면 될 것 같다. 그러나 HTML 속성값에 인터폴레이션을 쓰면 안된다. 왜냐하면 "" 안에 v-text 넣는거랑 같다. 그래서 googleUrl을 넣으면 된다. 그렇다면 v-bind는 언제 쓰나?
v-bind:표준속성 => 표준 HTML 속성과 Vue 인스턴스를 연동할 때 쓴다. Vue에서는 v-bind를 보는 순간 부터 자기가 처리해야한다는 것을 인지한다.
v-bind:를 줄여서 :으로 쓸수 있다.
+ 동적 바인딩
# v-bind 추가
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue Tutorial</title>
</head>
<body>
<div id="app-2">
<span v-bind:title="message">
내 위에 잠시 마우스를 올리면 동적으로 바인딩 된 title을 볼 수 있습니다!
</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app2 = new Vue({
el: '#app-2',
data: {
message: '이 페이지는 ' + new Date() + ' 에 로드 되었습니다'
}
})
</script>
</body>
</html>
동일한 값이 여러개라면 첫번째 찾은거만 연결이 된다.
연결된 태그 안쪽만 사용가능<div class=""></div>
<span v-bind:title="message">
-
title은 마우스 올리면 뜨게 하는 것
-
message는 키값
-
v-bind를 적어야 아래 부분과 연결이 된다.
new Date() : javascript 에서 제공하는 함수로 현재시간을 반환 해주는거다.
message: '이 페이지는 ' + new Date() + ' 에 로드 되었습니다'
message: `이 페이지는 ${new Date()} 에 로드 되었습니다.`
이렇게 백틱을 이용해서 가능하다. 위와 두줄은 같은 말이다
3.7 methods
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{{ message }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data : {
message: 'Hello Vue'
},
methods: {
alertWarning: function () {
alert('WARNING')
},
alertMessage () {
alert(this.message)
},
changeMessage () {
this.message = 'CHANGED MESSAGE'
},
}
})
</script>
</body>
</html>
const app = new Vue 안에 있는 딕셔너리를 보면, key와 value로 이루어져 있는 것을 알 수 있다. 이때, 반드시 key는 정해진 것으로 바꿔주면 안된다.
methods는 우리가 쓸 함수들의 집합이 들어가게 된다. methods는 데이터를 가지고 움직일 수 있게 해준다.
console창에 적을 때,
app.methods.alertWarning() 이라고 적으면 안된다. 왜냐하면 자체적으로 Vue에서 재정의를 하기 때문에 methods를 빼고 아래처럼 적어줘야한다.
아래와 같이 콘설 창을 열러서 app.alerWarning()을 치면 alert창이 뜬다.
3.7.1 Syntactic Sugar
alertMessage: function () {}과 alertMessage () {} 은 완전히 같은 말이다. 전자는 위에서 말한 원칙 중 하나인 딕셔너리 형태로 key와 value 형식으로 되어 있는 것이고, 후자는 전자의 형식에서 : function을 생략한 것이다. 이러한 작성법을 Syntactic Sugar라고 한다.
3.7.2 this.message
위의 코드에서 아랫부분만 가져와서 보자.
<script>
const app = new Vue({
el: '#app',
data : {
message: 'Hello Vue'
},
methods: {
alertMessage () {
alert(message)
}
}
})
</script>
이제 콘솔 창(인터넷 켜고 F12를 누른 후에 console버튼을 찾아서 누른다.)에서 다음을 치자
> app.alertMessage(message)
message를 못찾는다는 ERROR가 발생한다. 결론 부터 말하자면 아래처럼 this를 넣어서 수정해 줘야 콘솔 창에서 함수를 불렀을 때, 찾을 수 있다.
<script>
const app = new Vue({
el: '#app',
data : {
message: 'Hello Vue'
},
methods: {
alertMessage () {
alert(this.message)
}
}
})
</script>
자바스크립트에서 this란 매서드가 속해있는 객체라는 정의 때문에 상식 적으로는 this가 methods가 되야 정상이다. 그러나 Vue에서는 우리가 평소에 알고 있는 this가 아니라 전혀 다른 this로 속성이 바뀐다. 그렇다고 this.data.message로 메세지를 접근하는 것도 아닌, this.message로 접근하다. 이해 하려고 하지말자. 만든사람이 이렇게 만든거다. 그냥 외우자. (좀 더 알고 싶다면, 프록시라는 개념을 찾아서 공부해 보자. 다 뽑아서 재정렬 한다.)
즉, 재정렬을 하기 때문에 콘솔 창에서 app.methods.alertMessage() 라고 적어도 먹히지 않는다. app.alertMessage()로 적어야 불러짐이 된다.
3.7.3 this.message 변경해보기
<script>
const app = new Vue({
el: '#app',
data : {
message: 'Hello Vue'
},
methods: {
alertWarning: function () {
alert('WARNING')
},
alertMessage () {
alert(this.message)
},
changeMessage () {
this.message = 'CHANGED MESSAGE'
},
}
})
</script>
마지막으로 changeMessage 부분에 this.message 부분에 string을 넣어주는 것을 볼 수 있는데, 저 함수를 실행을 하면 기존에 'Hello Vue'였던 message가 'CHANGED MESSAGE'라는 문자열로 변경이 됨을 알 수 있다.
정리해 보면 methods는 함수의 집합이다. 그리고 methods 안의 함수들이 하는 일은 정적인 데이터들에 일을 시키거나 움직이게 한다. 즉, 가장 중요한 것은 data에 들어있는 key value이고, 그러한 data를 수정시키는 것이 method안의 함수라고 할 수 있다.
3.8 v-on (JS의 .addEventListener) -매우많이쓴다.
지금까지는 사용자가 쓸 수 있는 것은 없없다. v-on은 사용자와 엮기(ex. 마우스 클릭)가 가능하다.
<body>
<div id="app">
<h1>{{ message }}</h1>
<button v-on:click="alertWarning">Alert Warning</button>
<button v-on:click="alertMessage">Alert Message</button>
<button @click="changeMessage">Change Message</button>
<hr>
// 사용자가 넣은 입력으로 바꾸기
// 어떤키가 올라와도 실행
<input v-on:keyup.enter="onInputChange" type="text">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// el은 Vue 인스턴스의 속성이다.
const app = new Vue({
el: '#app',
data : {
message: 'Hello Vue'
},
methods: {
alertWarning: function () {
alert(WARNING)
}, //app.alertWarning 라고 치면 뜬다
alertMessage () { //Synntactic Sugar: 위 와 아래는 완전히 같습니다.
alert(this.message) //Hello Vue가 alert 뜬다.
}, // JS의 this와 뷰의 데이터는 다르다.
changeMessage() {
this.message = 'CHANGED MESSAGE'
},
onInputChange(event) {
//console.log(event.key) //이렇게 적으면 내가 누른 event가 출력
//if (event.key == "Enter"){ 위에 enter 하나 추가하면 이거 대체된다.
this.message = event.target.value
} //엔터 칠 때만 바뀐다.
}
})
</script>
- v-on: 을 줄여서 @으로 쓸 수있고 버튼을 누를 때 함수를 실행하게 하여 특정 변화를 줄 수 있게 한다.
- v-on:keyup 은 어떤 키든 눨렀다가 올라오면 실행되게 한다.
- onInputChange(event) 안에 console.log(event.key) 를 콘솔로 넣어주면, input에 적는 키보드 글자 하나하나당 console에 찍히게 된다. event가 들어가는 것은 자연스러운 현상이니 받아 들이자.
<input v-on:keyup="onInputChange" type="text">
###########################################
onInputChange(event) {
if (event.key == "Enter") {
this.message = event.target.value
}
}
이런 식으로 적는다면 input에서 글을 적고, 엔터를 누를 때면, message가 input안에 있는 내용이 된다.
위의 내용은 아래의 내용과 완전 같다.(v-on:keyup="onInputChange" => v-on:keyup.enter="onInputChange")
<input v-on:keyup.enter="onInputChange" type="text">
###########################################
onInputChange(event) {
this.message = event.target.value
}
keyup.space 로 적으면 spacebar를 칠 때마다 바뀌게 된다. 추가적으로 알고 싶다면 공식문서를 보면 된다.
아래와 같이 '코딩은 쉽다'라는 글을 치고 엔터를 누르면 {{message}} 부분에 글이 들어가는 것을 알 수 있다.
3.9 v-model
공식문서를 v-model은 보면 양방향 바인딩 이라고 강조 되어 있다. 그렇다면 바인딩이 뭘까? 먼저 v-model이 적용되지 않은 단방향 부터 살펴 보자.
3.9.1 단방향 바인딩
input이 데이터로 가게한다. Vue를 열어보면 input에 글을 적으면 자동으로 data로 들어가는 것을 볼 수 있다. 다시 말하면, input값이 Vue data에 영향을 주는데, Vue data를 변경한다 해도 input값에 영향을 주지 않는다.
<body>
<div id="app">
<h1>{{ message }}</h1>
// 단방향 바인딩(input이 data로 가게한다.)
// 데이터는 인풋에 영향을 끼치지 안는다.
<input @keyup="onInputChange" type="text">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data : {
message: 'hi',
},
methods: {
onInputChange(event) {
this.message = event.target.value
}
}
})
</script>
3.9.2 양방향 바인딩
데이터를 바꿔도 input 값을 바꾸는 것이 양방향 바인딩이다.
value는 표준 속성이다. 따라서 v-bind:value가 가능하다. 따라서 :value를 사용해서 message와 엮어주면 바인딩이 된다.그런데 이렇게 다 적기 힘들기 때문에 v-model로 간단히 적을 수 있게 만든 것이다. 함수도 필요 없고 value도 필요 없이 단지 v-model만 적어주면 된다.
<body>
<div id="app">
<h1>{{ message }}</h1>
// v-model은 input, select, textarea에 쓰이고 양방향 바인딩이다
<input @keyup="onInputChange" type="text" :value="message">
<hr>
// 단방향 바인딩(input이 data로 가게한다.)
// 데이터는 인풋에 영향을 끼치지 안는다.
<input @keyup="onInputChange" type="text">
<hr>
// 위의 양방향을 간단히 적기
<input v-model="message" type="text">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data : {
message: 'hi',
},
methods: {
onInputChange(event) {
this.message = event.target.value
}
}
})
</script>
사용자 입력과 data를 완전히 동기화 시키고 싶을 때 쓴다.
3.10 v-show( v-if 와 비교 ) _ 조건부 랜더링
<body>
<div id="app">
<p v-if="t">
This is v-if with true
</p>
<p v-if="f">
This is v-if with false
</p>
<p v-show="t">
This is v-if with true
</p>
<p v-show="f">
This is v-if with false
</p>
<button @click="changeF">changeF</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data : {
t: true,
f: false,
},
methods: {
changeF() {
this.f = !this.f
}
}
})
</script>
v-show는 개발자도구로 보면 false 부분의 코드가 보인다.(DOM에 있다.) t/f가 자주 바뀔 때 쓴다. 다시 렌더링이 필요 없다. 토글 코스트가 작다.
v-if는 개발자도구보면 코드가 true 부분의 코드가 안보인다.(= 화면에 랜더링 되지 않음) DOM에도 없다. t/f가 자주 안 바뀔 때 쓴다. 초기 랜더링 코스트가 작은 장점이 있다.(처음부터 안그린다.) html에 없던 게 등장을 해야하기 때문에 토글 코스트가 크다.
4. 실습
4.1 로또 만들기
# [1...45]인 배열에서 6개를 랜덤하게 뽑는다. (JS는 수학에 쥐약이다. 파이썬 처럼 random 라이브러리가 없다.)
그래도 필요하다면, 아래의 내용을 검색해보자. 즉, 수학 필요한데 구현이 안되면 lodash를 찾자
구글검색) lodash - 자바스크립트 라이브러리 들어가보면 다 구현해 놨다. (필요할 때 자주 쓸 것이다.)
구글검색) lodash CDN
<body>
<div id="app">
<button @click="getLuckySix">GET LUCKY 6</button>
<ul>
<li v-for="number in myNumbers">
{{ number }}
</li>
</ul>
</div>
<script>https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js</script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data : {
allNumbers: _.range(1, 46)
myNumbers: []
},
methods: {
getLuckySix() {
this.myNumbers = _.smpleSize(this.allNumbers, 6)
this.myNumbers.sort((a, b) => a-b) // 문자열-문자열은 정수가 되서 이렇게 적는거다.
}
}
})
</script>
CDN 가져오면 _ 쓰기 가능
.sot 하면 원본도 바뀐다. 그리고 특이하게 string으로 정렬해서 첫자리 부터 순차적으로 정렬된다.
따라서 콜백함수를 포함시켜야한다.
method 안에 함수를 정의해서 이벤트리스너랑 붙일 수 있다는 것은 자유도가 급상승한거다. 잡는것도 디렉티브로 바로 되고, 붙이는것도 자동으로 된다.
+ 추가 정리
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue Directive</title>
</head>
<body>
<div id="app-3">
<p v-if="seen">이제 나를 볼 수 있어요</p>
<p v-else>여긴 seen이 false 일 때 보여요.</p>
</div>
// 인덱스 가져오기 가능하다.
<div id="app-4">
<ol>
<li v-for="(todo, idx) in todos">
{{ todo.text }} ({{ idx }})
</li>
</ol>
</div>
// v-on적으면 이벤트리스터가 쉽다. 그리고 그 뒤에 동작을 적어준다(click)
<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">메시지 뒤집기</button>
</div>
// bind는 특정 속성의 값을 연결해준다. (bind와 v-model은 비슷해보이지만 다르다.)
// v-model은 input이나 textarea같은 입력을 받을수있는 form과 vue에 저장된 data와 연결시켜주는 역할
<div id="app-6">
<p>{{ message }}</p>
<input type="text" v-model="message">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})
// 카 적을 때 ''는 있어도 되고 없어도 된다.
var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: 'JavaScript 배우기' },
{ text: 'Vue 배우기' },
{ text: '무언가 멋진 것을 만들기' }
]
}
})
//익명합수의 this 는 vue 인스턴스
//글자 하나씩 스플릿하고 뒤집고 합친다.
var app5 = new Vue({
el: '#app-5',
data: {
message: '안녕하세요! Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
var app6 = new Vue({
el: '#app-6',
data: {
message: '안녕하세요 Vue!'
}
})
</script>
</body>
</html>
본격적으로 Vue에 대해 배우고 싶다면, 아래의 주소로 가자.
'Web > Vue.js' 카테고리의 다른 글
[Vue.js] 5. computed 기초 정리 (0) | 2020.12.07 |
---|---|
[Vue.js] 4. scrollmonitor(무한스크롤) 적용하기 (0) | 2020.12.05 |
[Vue.js] 3. lifecycle hook 적용하기 (0) | 2020.11.20 |
[Vue.js] 2. 데이터 받기(get) (0) | 2020.11.17 |
[djang-vue연동] Vue.js 1. 설치부터 시작 (0) | 2020.10.22 |
- Total
- Today
- Yesterday
- mongoDB
- react
- nodejs
- next.config.js
- Python
- logout
- error:0308010C:digital envelope routines::unsupported
- JavaScript
- 자연어처리
- BFS
- pandas
- read_csv
- nextjs autoFocus
- django
- TensorFlow
- Vue
- useState
- vuejs
- react autoFocus
- Queue
- typescript
- Express
- NextJS
- useHistory 안됨
- 자료구조
- DFS
- 클라우데라
- Deque
- login
- UserCreationForm
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |