[Vue] Vue 기본정리 part1
개발환경 세팅과 VUE3 버전 설치
Vue 설치부터 하도록 합시다. 문법 체험을 위해 HTML 파일에 라이브러리 식으로 간략하게 설치하는 방법은 쓰지 않고
실제 Web-app 개발에 필요한 Vue 프로젝트를 처음부터 만드는 식으로 진행합니다.
그러려면 Vue-cli 라는 라이브러리가 필요한데 그것 부터 설치하도록 합시다.
그리고 요즘은 설치과정 맥이나 윈도우나 똑같음
요약부터 하자면
- nodejs 최신버전 설치
우측 최신버전이 뭔가 에러가 덜 납니다.
그래도 에러나면 LTS 왼쪽 버전으로 바꾸실 수 있습니다. 제어판에서 삭제 후 재설치하셈
- VS code 에디터 설치
구글 검색해서 다운받고 설치하셈
- 아무데나 작업용폴더 만들고 에디터로 오픈
코딩실력이 부끄럽다면 은밀한 곳에 만들어줍니다. 에디터 상단 메뉴에 open folder라고 있을겁니다 그렇게 오픈하셈
▲ 에디터 왼쪽 위에 아까 만든 폴더명이 떠야합니다. 그럼 폴더오픈 제대로 잘한 것임
- 에디터에서 터미널 열고 npm install -g @vue/cli 입력
터미널은 에디터 상단 Terminal - New Terminal 누르면 됩니다.
입력 후에 Vue 3 버전을 방향키 + 엔터로 선택하면 됩니다.
안되면 90%확률로 nodejs 이상하게 설치해서 그렇습니다. 해결책은 하단에
뭔가 npm 하는거 부터 에러나면
yarn 1.22 버전 구글검색해서 설치하고 윈도우 재시작하고 yarn global add @vue/cli 이거 해보셈
윈도우는 yarn 1.22 인스톨러를 다운받아서 설치하고 컴퓨터 재시작,
맥은 터미널 아무데나 열고 npm install -g yarn 하시면 됩니다.
윈도우는 맥처럼 설치하면 컴퓨터 폭발함 그러지마세요
- 설치가 끝났으면 터미널에서 vue create 프로젝트명 입력
프로젝트명은 자유 작명 가능합니다.
그럼 하위폴더로 프로젝트폴더가 생성됩니다.
- 프로젝트명으로 생성된 폴더를 에디터로 오픈 후 코딩시작
하위폴더로 vuedongsan 생성된거 그거 다시 open folder 로 오픈하라는 소리입니다.
폴더오픈 안한채로 코딩하다가 뭐 안된다그러면 혼납니다.
여러 파일 중 App.vue에다가 코딩 시작하면 됩니다.
- 미리보고 싶으면 터미널 열고 npm run serve 입력
위에서 프로젝트 폴더 오픈 안해놨으면 에러가 날 수 있습니다.
- VS code 에디터 부가기능을 설치해줍니다
에디터 제일 왼쪽 네모네모 버튼 (Extensions) 누르면 됩니다. Vetur, Vue 3 snippets, HTML CSS Support 이거 세개 설치합니다.
하지만 설치과정에서 20% 확률로 에러가 뜹니다. 원래그럼
대부분 에러메세지 구글 검색으로 해결이 가능하지만 자주 겪는 에러를 알아보도록 합시다.
▶ 저는 설치가 10분이상 걸려요
인터넷 느리면 그렇습니다. 스타벅스에서 하지 말고 집에서 하시길 바랍니다.
▶ npm, yarn 명령어 입력하자마자 에러가 납니다
설치가 잘 되다가 갑자기 중간에 빨간게 뜨며 에러가 나는 대부분의 경우는
99%확률로 nodejs가 최신버전이 아닐 경우 입니다.
- nodejs 삭제 후 2. 다른 버전 다운받아서 다시 시도해보십시오
▶ npm : command not found 에러
npm : command not found 라는 에러가 뜨는 것은 역시 99%의 확률로 node 이상하게 설치하셔서 입니다.
nodejs 설치시 설치경로 만지지 마십시오.
맥도 brew 어쩌구 그런걸로 설치하지 마시고 다운받으세요.
리눅스는 nodejs 버전 업그레이드 커맨드 찾아서 입력하시면 되니 알아서 잘 하시리라 믿습니다.
▶ 맥에서 permission이 없어요, 권한이 없어요 이런 에러가 뜬다면
직관적인 해결책은 그냥 npm이나 yarn 쓰실 때 앞에 sudo 라는 단어를 붙여주시면 됩니다.
sudo npm install -g @vue/cli 이런 식으로 하면 잘 됩니다
설치 중간에 여러분 맥북 비번입력이 필요할 수 있습니다.
근데 sudo는 임시방편일 뿐입니다.
npm ERR! syscall access
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
▲ 예를 들면 이런 에러인데 폴더 수정 권한이 없다고 에러를 띄우는 거면
위의 경우 /usr/local/lib/node_modules 라는 폴더에 수정권한을 주시면 됩니다.
터미널을 켜서 이거 둘 중에 하나를 입력해보십시오
sudo chown -R 님맥북유저이름: 위에에러뜬경로
sudo chown -R $USER 위에에러뜬경로
아마 둘 중 하나 입력하시면 대부분 해결될 겁니다.
님맥북유저이름은 터미널에 whoami 입력하시면 나옵니다.
역시 이것도 임시방편이긴 한데
이거 말고도 다른 경우가 있을 수 있으니 그대로 구글에 에러메세지 검색해보시면 되겠습니다.
▶ 윈도우 Powershell에서 빨간글씨로 ‘보안오류’가 뜹니다.
“허가되지 않은 스크립트 입니다 어쩌구~” 그런 에러가 뜨면
윈도우 검색메뉴 (돋보기) - Powershell 검색 - 우클릭 - 관리자 권한으로 실행한 뒤
Set-ExecutionPolicy Unrestricted
라고 대소문자 하나라도 틀리지않고 입력하십시오.
그럼 이제 npm으로 뭐 하는거 잘됩니다.
▶ 윈도우 Powershell을 이용하는 경우도 권한이 없다고 뭐라 그럴 수 있습니다.
그렇다면 윈도우 검색메뉴에서 powershell을 검색 후 우클릭 - 관리자 권한으로 실행합니다.
그 다음에 npm install -g @vue/cli 를 입력하거나
yarn global add @vue/cli 를 입력합니다.
그럼 됩니다.
이 경우 vue create 어쩌구 할 때도
작업폴더를 오픈한 뒤에 상단 메뉴에서 파일 - powershell열기 - 관리자 권한으로 powershell 열기 누르신 후 입력해보십시오.
HTML에 데이터 넣는 Vue 데이터바인딩 문법
일단 이렇게 생긴 데이터를 하단에 하나 저장하십시오.
products : [‘역삼동원룸’, ‘천호동원룸’, ‘마포구원룸’]
▲ 그 데이터와 문법으로 대충 이렇게 생긴 HTML 레이아웃을 만들어오십시오.
가격은 대충 임시로 아무거나 기입하시길 바랍니다.
HTML에 자바스크립트 데이터를 꽂아넣고 싶을 때가 있습니다.
데이터바인딩이라고 하는데
Vue에서 데이터바인딩 하는 문법을 2개 알아보도록 합시다.
근데 애초에 데이터바인딩을 왜 하는지 의문점 부터 들지 않습니까.
그런거 궁금해해야 나중에 여러분 데이터 바인딩 할지 말지 스스로 판단하는 훌륭한 사람이 됩니다.
그것 부터 알아봅시다.
Vue 개발은 어려운게 아닙니다
어딜가나 이상한 문법부터 가르치니까 혼자 코드짜는거 어려워들 하시는데
그냥 평소에 HTML CSS로 웹페이지 개발하던 대로 쭉 코드짜시면 되고
필요한 순간순간 Vue 문법을 첨가하면 됩니다.
그래서 원룸파는 쇼핑몰을 한번 만들어봅시다. 일단 레이아웃 부터요.
<template>
<div>
<h4>XX 원룸</h4>
<p>XX 만원</p>
</div>
<div>
<h4>XX 원룸</h4>
<p>XX 만원</p>
</div>
</template>
HTML 코드들은 <template>
안에 집어넣으면 됩니다.
자바스크립트 기능은 <script> 스타일은 <style>
안에 넣으십시오.
그래서 아무튼 저런 HTML을 추가하십시오. 배울 문법이 하나 있어서 그렇습니다.
Vue의 데이터바인딩 문법
JavaScript로 자주 하는 짓거리가 있습니다.
자바스크립트 변수나 데이터를 HTML에 꽂아넣는 데이터바인딩입니다.
전통방식은 이렇게 길게 한줄 써야 데이터바인딩이 가능했습니다.
document.getElementById(어쩌구).innerHTML = 데이터;
근데 Vue는 그럴 필요없이
일단 데이터보관부터 어딘가에 하시고
그걸 이런 문법으로 HTML 중간중간에 쉽게 꽂아넣을 수 있습니다.
data보관함은 여기있습니다.
<script>
export default {
name : 'App',
data(){
return {
price1 : 60
}
}
}
</script>
script 태그 안에 data(){ return { } } 이걸 열고
데이터를 object 형식으로 저장하시면 됩니다.
이게 Vue의 data보관함, 변수보관함이라고 보시면 되겠습니다.
중요한 데이터는 다 여기 보관하십시오. 중괄호니까 object 형식에 맞춰서요.
그럼 이제 price1 이라는 데이터를 HTML안에 꽂아넣어서 유저에게 보여주고 싶으면
이것만 쓰면 됩니다.
<p> 만원</p>
저장하면 브라우저에 60만원이라고 잘 뜹니다.
Q. 뭐임 그냥 애초에 <p>60만원</p>
이렇게 하드코딩하면 되는데
굳이 데이터로 저장해뒀다가 왜 데이터바인딩함?
이유1. 쇼핑몰은 가격이 맨날 변동되지않습니까.
그걸 데이터로 저장해놓으면 수정이 나중에 편리합니다.
JS로 조작이 쉽거든요
이유2. Vue의 실시간 렌더링기능 쓰려면 데이터바인딩 해놓으십시오
Vue는 신기해서 data가 변경되면 data와 관련된 HTML에 실시간으로 반영됩니다.
만약에 여러분이 price1을 60에서 70으로 조정하면
에도 그 변경사항이 바로 적용된다는 소리입니다.
따로 코드짤 필요 없이 자동으로 샥 바뀝니다.
그리고 이런 사이트를 우리는 웹앱이라고 부릅니다.
그래서 웹앱 만들고 싶으면 좋은 말할 때 자주 바뀔 듯한 데이터들을 data란에 집어넣고
데이터바인딩해서 보여주시길 바랍니다.
HTML 속성도 데이터바인딩이 가능합니다.
그니까
style="" id="" class=""
이런 것들에도
밑에 저장해둔 data를 꽂아넣을 수 있다는 것입니다.
<template>
<div>
<h4 :style="스타일">XX 원룸</h4>
<p>XX 만원</p>
</div>
<div>
<h4>XX 원룸</h4>
<p>XX 만원</p>
</div>
</template>
<script>
export default {
name : 'App',
data(){
return {
price1 : 60,
스타일 : 'color:red'
}
}
}
</script>
이렇게 짜시면 color : red라는 데이터도 원하는 곳에 꽂아넣을 수 있습니다.
상상하는 모든 속성에 데이터 꽂아넣기가 가능합니다.
리액트보다 100배 쉬운 Vue 반복문 v-for
5분 숙제 :
v-for 문법을 이용해 지금 있는 상품목록을 반복문으로 축약해보십시오.
가격은 신경쓰지말고 상품제목만 잘 보이면 됩니다.
저번시간 숙제는 어떻게 했냐면
저번 시간에 하단에 데이터로
products : [ ‘역삼동원룸’, ‘천호동원룸’, ‘마포구원룸’ ]
이렇게 3개의 상품명을 저장하라고 했습니다.
그 다음 3개의 상품명을 저기 HTML에다가 데이터바인딩하라고 했습니다.
고민할 것 없이 중괄호 문법으로 데이터를 꽂아넣으면 됩니다.
<div>
<h4></h4>
<p>50만원</p>
</div>
<div>
<h4></h4>
<p>50만원</p>
</div>
<div>
<h4></h4>
<p>50만원</p>
</div>
HTML을 짜다보면 비슷한 div 이런게 수백번 출몰하지 않습니까.
그걸 보고 있으면 비슷한 div들을 간단하게 for 반복문 같은 걸로 축약하고 싶은 충동이 들지 않습니까.
리액트나 Vue를 쓰면 가능합니다. 그리고 그런 장점 때문에 리액트와 Vue를 쓰는겁니다.
하지만 for, map, forEach 이런 문법 배우다 포기하셨다면
Vue 반복문은 100배 쉬우니 걱정하지 맙시다.
상단 메뉴를 만들어봅시다
페이지가 여러개 있는 것은 아니지만 심심하니 상단메뉴를 만들어봅시다.
HTML과 CSS는 다음과 같이 작성합니다.
CSS는 vue파일 하단 style 태그 안에 넣으면 됩니다.
<div class="menu">
<a>Home</a>
<a>Products</a>
<a>About</a>
</div>
.menu {
background : darkslateblue;
padding : 15px;
border-radius : 5px;
}
.menu a {
color : white;
padding : 10px;
}
v-for HTML 반복문
가끔 코드를 짜다가
HTML에 반복되는 부분이 보이면 축약하고 싶은 충동이 듭니다.
이걸 축약하고 싶으면 v-for을 쓰면 됩니다.
v-for쓰시면 원하는 만큼 HTML 태그를 복붙할 수 있습니다.
예를 들어서 위에서 작성했던 a태그 3개를
한줄 컷으로 생성하는 마법을 보여드리겠습니다.
<div class="menu">
<a v-for="작명 in 3" :key="작명">Home</a>
</div>
원하는 태그에 v-for=”작명 in 반복할횟수” 를 적습니다.
그리고 센스있게 :key=”작명” 이것도 추가해줍니다.
그럼 이 HTML 태그는 내가 원하는 만큼 반복생성됩니다.
위의 예제는 Home이라는 a태그가 3개나 생성되겠네요.
작명은 아무렇게나 하시면 됩니다. 변수하나 작명하는 겁니다.
:key 속성은 반복문돌릴 때 꼭 필요합니다. 반복한 요소들을 각각 구분짓기 위한 속성입니다.
v-for HTML 반복문2
v-for 반복문을 사용할 때 array, object 데이터를 집어넣을 수도 있습니다.
예를 들어서 array 자료를 하나 만들어봅시다. 데이터로 저장해두십시오.
data(){
return {
메뉴들 : ['Home', 'Shop', 'About']
}
}
그럼 이제 메뉴들 이라는 데이터로 반복문을 돌릴 수도 있다는 겁니다.
<div class="menu">
<a v-for="작명 in 메뉴들" :key="작명">Home</a>
</div>
아까랑 사용하는 법은 똑같은데 반복시킬 횟수 적는 란에다가 array 자료를 집어넣을 수 있습니다.
이 경우
메뉴들안의 자료 갯수만큼 반복됩니다.
작명한 변수는 반복될 때마다 메뉴들 안에 있던 자료들이 됩니다.
예를 들어서 작명한 변수는 출력해보면 1회 반복시엔 ‘Home’ 2회 반복시엔 ‘Shop’ 이렇게 변한다는 겁니다.
<div class="menu">
<a v-for="작명 in 메뉴들" :key="작명"> </a>
</div>
그래서 작명한 변수를 저기 실제로 출력해보면 (데이터바인딩해보면) 진짜 그렇죠?
a태그가 3번 생성되는데 생성될 때마다 부분은 차례로
Home이 되고 Shop이 되고 About이 됩니다.
그래서 밑에 있는 array, object 데이터 안에 있던 자료들을
하나씩 HTML로 만들어서 보여주고 싶을 때도 v-for을 쓰시면 유용합니다.
v-for 안에 변수는 2개까지 작명이 가능합니다.
<div class="menu">
<a v-for="(작명,i) in 메뉴들" :key="i"> </a>
</div>
() 소괄호를 여시면 작명을 두개까지 허용해줍니다.
첫째 작명한건 아까 설명했던 array안의 데이터가 되는 것이고
둘째 작명한건 0, 1, 2 .. 이런 식으로 1씩 증가하는 정수가 됩니다.
반복 횟수를 알려주는 숫자라고 보시면 되겠습니다.
그래서 i는 출력해보시면 반복될 때마다 0, 1, 2.. 이렇게 변할걸요
그리고 이걸 보통 관습적으로 :key 안에 집어넣습니다.
그래서 결론은 HTML 복붙하기 힘들면 쓰시길 바랍니다.
아니면 혹은 HTML을 데이터 갯수만큼 자동으로 생성하고 싶으면 쓰십시오.
Vue이벤트 핸들러로 Click 감지하기(허위 매물 신고 버튼 만들기)
5분 숙제 :
모든 상품에 신고버튼과 기능을 만들어오십시오.
상품마다 각각 신고수를 따로 집계해야합니다. 그래서 신고수 3개를 각각 저장할 공간이 미리 필요하겠군요.
저번시간 숙제
div 3개를 하드코딩해서 만들었던 상품목록을
v-for 반복문으로 멋있게 축약해서 상품목록을 만들어오라고 했습니다.
그래서 전 이렇게 했다고 합니다.
일단 하단에 products라는 이름으로 데이터를 저장해놨는데
그거 갯수만큼 v-for 반복문을 돌리기로 했습니다.
<div v-for="(a,i) in products" :key="i">
<h4></h4>
<p>50만원</p>
</div>
그래서 이렇게 적었다고 합니다. 끝
반복문을 돌리면서 products[i]를 상품명으로 출력하라고 해놨습니다.
이거 대신 a라고 쓰셔도 똑같겠군요
어떤 HTML 요소를 클릭했을 때 뭔가 일이 일어나게 만들고 싶으면
<div onclick=""> 이 안에 자바스크립트를 집어넣습니다.
Vue에서는 살짝 다르게 집어넣으면 됩니다. @click=”” 이걸 집어넣으면 됩니다.
문법만 설명하면 다음날 다 까먹을게 분명하니
저번시간까지 만들던 부동산 사이트에 허위매물 신고버튼과 기능을 만들어보며 배워봅시다.
허위매물 신고버튼과 신고수를 만들어봅시다
일단 저번시간 반복문 돌린건 복잡해보이니까 다시 원래대로 복구시킵니다.
<div>
<h4></h4>
<p>50만원</p>
</div>
<div>
<h4></h4>
<p>50만원</p>
</div>
<div>
<h4></h4>
<p>50만원</p>
</div>
우리같은 빡대가리들은 간단한걸 좋아하기 때문입니다.
여기다가 버튼을 하나 추가해보자는겁니다.
<div>
<h4></h4>
<p>50만원</p>
<button>허위매물신고</button>
<span>신고수 : 0</span>
</div>
이거 버튼을 누르면 옆에 있는 신고수가 1 증가하는 기능을 만들어볼겁니다.
그러려면 어떻게 해야할지 생각해봅시다.
일단 신고수를 기록할 수 있는 변수나 데이터가 하나 필요하지 않을까요?
data(){
return {
신고수 : 0,
}
}
<div>
<h4></h4>
<p>50만원</p>
<button>허위매물신고</button>
<span>신고수 : {신고수}</span>
</div>
- 그래서 하단에 데이터를 하나 만들고 2. 데이터를 HTML란에 꽂아넣었습니다.
이제 버튼을 누르면 신고수라는 데이터를 1증가시키면 신고수가 1이 되고 HTML도 재렌더링이 되고
원하는 기능이 완성될 것 같습니다.
버튼을 누르면 기능을 실행하고 싶은 경우
자바스크립트는 onclick=”” 이라는 이벤트 핸들러를 HTML태그에 달았지만
Vue에서는 @click=”” 이라고 사용합니다.
그럼 안에다가 자바스크립트를 자유롭게 입력가능합니다.
<div>
<h4></h4>
<p>50만원</p>
<button @click="신고수++">허위매물신고</button>
<span>신고수 : {신고수}</span>
</div>
이거 버튼을 누르면 신고수라는 데이터를 +1 해주고 싶어서 저렇게 작성했습니다.
그럼 버튼 누를 때마다 신고수가 +1 됩니다. 끝!
신고수++
신고수+=1
아무렇게나 작성할 수 있습니다.
@click 말고 다른 이벤트 핸들러도 만들 수 있습니다.
@mouseover 하면 클릭이 아니라 마우스만 댔을 때 자바스크립트를 실행가능하고
@input 하면 인풋에 값을 입력했을 때 자바스크립트를 실행가능하고
님들이 알던 이벤트명을 자유롭게 기입해주면 됩니다. 모르면 어쩔 수 없이 @click이나 씁시다.
코드가 길 경우 함수를 만들어씁니다
긴 코드를 짧게 축약해주는게 바로 함수문법입니다.
그래서 @click 안에 들어갈 말이 너무 길다면 함수를 만들어서 집어넣으십시오.
함수 만드는 자리는 이미 정해져있습니다. 밑에서 methods : {} 라는 항목을 신설해주면 됩니다.
data(){
return {
신고수 : 0,
},
methods : {
increase(){
this.신고수 += 1
}
}
}
methods라는 항목을 만드신 후
함수를 안에다가 계속 만들어낼 수 있습니다. 함수만들 땐 함수이름(){} 이게 끝입니다.
그리고 이건 꼭 기억해야하는 부분인데
여기서 데이터를 가져다쓰고 싶으면 꼭 this.데이터이름 이라고 사용해야합니다.
this는 그냥 위에 있는 데이터와 함수를 담은 큰 object라고 생각하시면 되겠습니다.
그리고 아까 HTML 부분에서 함수를 자유롭게 사용하면
아까 축약했던 this.신고수+=1 이게 실행됩니다. 끝
<div>
<h4></h4>
<p>50만원</p>
<button @click="increase()">허위매물신고</button>
<span>신고수 : {신고수}</span>
</div>
함수() 이렇게 하셔도 되고
함수이름만 쓰셔도 됩니다. @click=”increase” 이렇게요.
함수는 한글로 작명하면 잘 안될 수 있습니다.
v-if와 모달창 만들기(Vue에서 동적인 UI만드는 법)
5분 숙제 :
모달창 닫기버튼과 기능을 만들어오십시오.
신고버튼 3개 만들어오라는 저번시간 숙제 저는 어떻게 했냐면
<button>허위매물신고</button>
<span>신고수 : 0</span>
<button>허위매물신고</button>
<span>신고수 : 0</span>
<button>허위매물신고</button>
<span>신고수 : 0</span>
버튼과 신고수표시를 3개 만들어두면 됩니다. 그리고 여기 기능을 개발하면 되겠습니다.
각각 신고수는 다르게 동작해야합니다.
그래서 저는 일단 데이터를 이렇게 만들어놨습니다.
data(){
return {
신고수 : [0,0,0]
}
}
왜냐면 상품이 3개인데 그럼 각각 신고수를 기록할 공간도 3개 있어야하지 않겠습니까.
array 자료를 사용했습니다.
그리고
0번째 상품에는 신고수[0]을 표기해주고
0번째 신고버튼을 누르면 신고수[0]++
1번째 상품에는 신고수[1]을 표기해주고
1번째 신고버튼을 누르면 신고수[1]++
…
를 해주면 기능개발 끝일 듯요
▲ 그래서 대충 이런 식으로 했더니 성공했습니다.
하지만 혼자 열심히 해보는게 가장 중요합니다
그대로 따라해봤자 따라쟁이밖에 더 됩니까
오늘은 상품을 누르면 뜨는 상세페이지를 만들어볼 건데
실제 페이지를 다르게 이동시키는건 아니고 모달창 스타일로 만들어봅시다.
▲ 모달창이 뭐냐면 그냥 배경까맣고 안에 하얀 창있는 UI를 뜻합니다.
상품명을 클릭하면 이걸 띄워볼겁니다.
하지만 모달창만 배웠다고 모달창만 만들 수 있는 사람이 되면 안되기 때문에
Vue로 동적인 UI 만드는 Step을 설명해드리겠습니다.
현재 HTML UI의 상태를 데이터로 저장해둠 (지금 보이는지 안보이는지 이런거)
그 상태에 따라 HTML UI을 보여줄지 말지를 Vue문법으로 작성함
이것만 기억해두시면 모달창 말고도 탭, 서브메뉴 등 누르면 동작하는 UI들은 구글 도움 없이도 알아서 만들 수 있게됩니다.
말이 추상적이라 뭔지 아직 모르겠으면 모달창이나 따라 만들어봅시다. 그럼 이해됩니다.
그 전에 잠깐 이미지 넣는 법
이미지를 src 폴더 안에 아무데나 넣으시고
<img src="./경로">
를 적으시면 이미지 나옵니다. 끝
public 폴더에 넣으실 거면 약간 다른데 /경로라고 적으면 됩니다.
(public 폴더에 넣으면 나중에 발행할 때 이미지가 이름이 변하지않습니다 src는 임의로 바꿔줌)
배운 기념으로 하단에 첨부된 원룸들 이미지를 집어넣어보십시오.
이미지 크니까 이미지에다가 width와 margin-top 이런 걸로 스타일링좀 해보시고요.
모달창 만들기
뭔가 버튼누르면 모달창을 띄워보고 싶으면
모달창부터 HTML CSS로 만드시길 바랍니다.
뭔가 갑자기 등장하는 UI들은 다 미리 만들어놓고 원할 때 띄워주는 방식이니까요.
<div class="black-bg">
<div class="white-bg">
<h4>상세페이지</h4>
<p>상세페이지내용임</p>
</div>
</div>
body {
margin : 0;
}
div {
box-sizing: border-box;
}
.black-bg {
width: 100%; height:100%;
background: rgba(0,0,0,0.5);
position: fixed; padding: 20px;
}
.white-bg {
width: 100%; background: white;
border-radius: 8px;
padding: 20px;
}
이렇게 HTML과 CSS를 어딘가에 짜놓으시길 바랍니다.
이번 HTML 코드는 좀 위에 적는게 좋습니다.
근데 기능개발 어떻게 할겁니까. 상품제목을 누르면 모달창이 뿅하고 떠야합니다.
그냥 Vue로 동적인 UI 만드는 Step을 설명해드리겠습니다.
현재 HTML UI의 상태를 데이터로 저장해둠 (지금 보이는지 안보이는지 이런거)
그 상태에 따라 HTML UI를 보여줄지 말지를 Vue문법으로 작성함
이것만 기억해두시면 모든 UI기능은 거의 다 혼자 만들 수 있을걸요
그래서
- 현재 모달창의 상태를 데이터로 저장해둡니다.
모달창은 보이는/안보이는 상태만 존재합니다. 그래서 이걸 데이터로 표현해서 저장해두라는 소리입니다.
data(){
return {
모달창열렸니 : true,
}
}
저는 이렇게 true/false로 나타내고 싶어서 저렇게 써놨습니다.
0또는 1 이렇게 표현해도 전혀 상관없습니다 님들 맘임
미리 채워놓는 값은 기본값이라고 생각해도 되겠습니다.
1번기능 개발 끝
- 데이터 상태에 따라 HTML UI을 보여줄지 말지를 Vue문법으로 작성함
false면 숨기고 true면 아까 만든 <div>를 보여주자는 겁니다.
그러려면 하나의 새로운 문법이 필요합니다.
HTML 태그 안에 v-if=”조건식”을 사용하면 조건식이 참일 때만 HTML을 보여줍니다.
간단한 Vue 문법인데 이거 쓰면 2번을 구현가능합니다.
<div class="black-bg" v-if="모달창열렸니 == true">
<div class="white-bg">
<h4>상세페이지</h4>
<p>상세페이지내용임</p>
</div>
</div>
그래서 이렇게 쓰면 모달창열렸니라는 데이터가 true일 때만
div를 보여주는겁니다.
2번 개발 끝입니다.
그럼 모달창 셋팅이 완료된겁니다.
이제 여러분은 모달창열렸니 라는 데이터를 조작하면 모달창을 켜고 끌 수 있습니다.
UI만들 땐 일종의 스위치같은걸 미리 만들어둔다고 생각하면 됩니다.
스위치만드는 법은 저렇게 1번 2번 따라주면 되고
스위치를 켜고 끄는건 ‘모달창열렸니’라는 데이터를 조작하면 끝 아니겠습니까.
Q. 그럼 상품제목을 눌렀을 때 모달창을 열려면 코드 어떻게짜죠?
그니까 ‘모달창열렸니’ 스위치를 켜려면 어떻게 코드짭니까.
전 강의에서 배운건 알아서 해보시길 바랍니다.
오늘의 상식 :
data(){} 이 부분을 리액트 이런 곳에선 state라고 부릅니다.
뭔가 정보 저장하는 곳이기도 하고
UI의 현재 상태를 저장하는 곳이기도 하니까요.
상태는 영어로 state입니다.
실제 데이터를 박아넣어 상품 목록을 만들자.
5분 숙제 :
반복문으로 상품목록을 6개 만들어오십시오. 실제 상품데이터가 잘 반영되어있어야합니다.
강의에서 사용할 실제 상품데이터
오늘은 실제 원룸 데이터를 HTML에 꽂아 보여주도록 합시다.
서버가 있으면 서버에서 데이터를 받아와서 보여주는게 일반적이지만
우리는 그런게 없으니 가짜 데이터를 직접 준비했습니다.
위의 코드를 data() 란에다가 보관한 후 하면 되겠습니다. 하지만 데이터가 상당히 길어보입니다.
그대로 붙여넣으면 복잡해질 것 같으니 import/export 문법을 이용해서 다른 js파일에 보관한 뒤 가져오도록 합시다.
export default / import 문법
어떤 js 파일에서 만든 변수나 자료를 다른 js 파일에서 사용하고 싶은 경우 export와 import 문법을 씁니다.
일단 다른파일에서 export 하셔야 다른 파일에서 import를 할 수 있습니다.
막번역을 하자면 수출을 해야 수입을 할 수 있습니다.
예를 들어서 oneroom.js 에 있는 변수를 App.vue 에서 쓰고 싶은 경우
(oneroom.js)
var apple = 10;
export default apple
(App.vue)
import 어쩌구 from './oneroom.js파일경로'
이렇게 씁니다. export default 옆에 내보낼 변수나 자료형입력하면 되고
이걸 가져다가 쓰고싶으면 원하는 파일에서 import 작명 from 경로 적어서 사용하면 됩니다.
작명한 변수는 출력해보면 oneroom.js에서 export 했었던 10이라는 데이터가 나옵니다.
export default는 파일 맨마지막에 딱 한번 사용가능합니다.
import시 작명은 자유롭게 가능
export {} / import 문법
export 해야할게 많으면 export {} 문법을 사용합니다.
예를 들어서 oneroom.js 에 있는 변수들을 App.vue 에서 쓰고 싶은 경우
(oneroom.js)
var apple = 10;
var apple2 = 100;
export { apple, apple2 }
(App.vue)
import { apple, apple2 } from './oneroom.js파일경로'
이렇게 작성합니다.
export는 원하는 만큼 사용가능합니다.
이걸 import 시엔 작명이 불가능하고 export 했던 변수명 그대로 적어야합니다.
그래서 위에 첨부해드린 긴 데이터를 oneroom.js 에 저장해두시고
그걸 App.vue의 데이터로 저장하려면 코드 어떻게 짭니까.
알아서 해보시길 바랍니다.
(oneroom.js)
export default 위에있던원룸데이터
(App.vue)
import data from './oneroom.js파일경로'
data(){
return {
원룸들 : data
}
}
이렇게 작성했습니다.
원룸들이라는 이름으로 저장해뒀습니다.
이제 이걸 실제 상품명 자리에 집어넣고 싶으면 어떻게합니까.
데이터바인딩하면 됩니다. 이런 식이겠군요.
근데 원룸들이라는 데이터는 [ {}, {}, {}, {}, {}, {} ] 이렇게 생겼습니다.
왜냐면 제가 그렇게 만들었거든요
{} 하나마다 하나의 상품데이터가 들어있습니다. 상품명, 가격 이런 정보들이요.
그걸 꺼내서 첫째 상품에 집어넣으시면 됩니다.
예를 들어서
<div>
<img src="">
<h4></h4>
<p></p>
</div>
이렇게 데이터바인딩하시면 첫째 상품의 제목이 잘 데이터바인딩됩니다.
중괄호 대괄호가 뭔지 모르겠다면 자세한 설명은 강의에 있다고합니다.
##모달창에 상세 페이지 만들기
5분 숙제 :
오늘 만들었던 모달창 내의 내용을 알아서 꾸며보시길 바랍니다.
대충 상품명, 상품설명, 가격, 이미지 정도만 기입하면 됩니다.
저번시간 숙제는 어떻게 했냐면 저는 이렇게 했다고 합니다.
<div v-for="(a, i) in 원룸들" :key="i">
<img :src="a.image" class="room-img">
<h4 @click="모달창열렸니 = true"></h4>
<p></p>
</div>
원룸들을 반복문 돌려버리면
원룸들 안에 있던 자료 갯수만큼 반복문이 됩니다. <div>가 6회 생성되겠군요.
첫째 작명한 a라는 변수는 안에 있던 자료가 됩니다. {} 이거가 되겠군요.
그리고 제목을 누르면 모달창 여는 코드도 작성해놨습니다.
일단 상품제목 누르면 모달창 띄우는 코드 부터 다시 작성해봅시다.
모달창을 만들었는데 내용이 아무것도 없군요.
여기에 실제 상품의 상세내용을 출력해주고 싶습니다.
첫째 상품을 누르면 첫째 상품의 제목, 가격, 설명
둘째 상품을 누르면 첫째 상품의 제목, 가격, 설명
…
이렇게 모달창 안에 출력하려면 코드를 어떻게 짜면 될까요?
실은 저번에 모달창만들 때 했던 2-step 그대로 적용해보셔도 가능합니다.
0번상품을 누르면 0번제목이 모달창안에 떠야합니다
저번 모달창을 이렇게 수정하면 되는게 아닐까요
<div class="black-bg" v-if="모달창열렸니 == true">
<div class="white-bg">
<h4></h4>
<p>상세페이지내용임</p>
</div>
</div>
이렇게 작성하면 원룸들데이터 [ {}, {}, {}, {}, {}, {} ] 중에 0번째 제목이 저기 모달창에 박히겠죠.
근데 0번째 제목 맞습니까? 아마 이렇게 되어야하지 않을까요.
<div class="black-bg" v-if="모달창열렸니 == true">
<div class="white-bg">
<h4></h4>
<p>상세페이지내용임</p>
</div>
</div>
사용자가 방금 누른 상품번호를 여기 넣어야겠군요.
그니까 1번상품 누르면 1이 되는 변수
2번상품 누르면 2가 되는 변수를 넣자는 겁니다.
그럼 모달창이 완성될 듯 합니다.
그래서 누른거라는 데이터를 밑에다가 신설했습니다.
data(){
return {
누른거 : 0
}
}
여기다가 “사용자가 누른 상품번호”를 저장하기로 했고
이게 1로 바뀌면 1번상품제목, 2로 바뀌면 2번상품제목이 모달창에 잘 보이겠네요
그럼 이제 뭐해야합니까
사용자가 1번상품제목 누르면 저거 누른거를 1로 바꾸면 되는거 아니겠습니까.
<div v-for="(a, i) in 원룸들" :key="i">
<img :src="a.image" class="room-img">
<h4 @click="모달창열렸니 = true; 누른거 = i"></h4>
<p></p>
</div>
각 상품명을 누르면 누른거도 바뀌도록 만들어놨습니다.
X번상품 제목을 누르면 누른거가 X로 바뀝니다.
총 정리를 하자면
X번상품을 누르면 누른거라는 data가 X로 바뀜
그럼 모달창 안에 이것도 실시간 재렌더링됨 (관련된 data가 바뀌었으니까요)
그럼 모달창 제목이 이렇게 나옵니다.
어떻게 보면 저번시간 UI만드는 2-step이랑 비슷합니다.
상세페이지도 일종의 UI라고 볼 수 있기 때문에
상세페이지UI 상태를 미리 저장해두고
그 상태에 따라 HTML이 어떻게 보일지 작성
그럼 스위치가 완성됩니다.
그리고 필요할 때 버튼누르면 스위치 껐다켜고 그러면 된다고 했습니다.
v-else 라는 문법도 있습니다
v-if=”” 는 조건식이 참일 경우에만 특정 HTML을 보여줄 수 있다고 했습니다.
근데 v-else 이런 것도 있습니다.
<div v-if="1 == 2">
안녕하세요
</div>
<div v-else>
안녕하세요2
</div>
v-if 에 적은 조건식이 참이 아닐 경우에 v-else를 보여줍니다.
조건에 따라서 이거 혹은 저거를 보여주고 싶을 때 사용합니다.
<div v-if="1 == 2">
안녕하세요
</div>
<div v-else-if="1 == 3">
안녕하세요2
</div>
자바스크립트 else if 문법처럼
조건식을 연달아서 두개 세개 검사해보고 싶을 때 사용하시면 되겠습니다.
참고하시고 숙제로 모달창 내용이나 멋있게 완성해오도록 합시다.
HTML 복잡해보이면 컴포넌트 Component 만들어 쓰자.
모달창안에 꾸며오라는 저번시간 숙제는 어떻게 했냐면
대충 실제 상품들 다 박아오라고 했습니다.
그래서 이미지, 가격, 내용 이런 것들을 추가했다고 합니다.
<div class="black-bg" v-if="모달창열렸니 == true">
<div class="white-bg">
<img :src="원룸들[누른거].image" style="width:100%">
<h4></h4>
<p></p>
<p> 원</p>
<button @click="모달창열렸니 = false">닫기</button>
</div>
</div>
HTML 짜다보면 div 수십개 나오는게 일상입니다.
이게 싫으면 컴포넌트를 만들어서 사용하면 됩니다.
원하는 HTML 덩어리를 한 글자로 축약할 수 있게 도와주는 문법이 컴포넌트입니다.
할인배너를 하나 만들고 싶습니다
지금 원룸 결제하면 20% 할인해준다고 배너를 띄우고 싶어진 겁니다.
그래서 하나 HTML로 만들어봤습니다.
<div class="discount">
<h4>지금 결제하면 20% 할인</h4>
</div>
근데 이 코드가 너무 길고 복잡한겁니다.
안그래보이지만 그렇다고 가정해봅시다.
그럴 때 긴 HTML을 짧게 축약하는 컴포넌트문법을 쓰시면 됩니다.
컴포넌트 만드는 법
컴포넌트 만드는 법을 요약하자면
어쩌구.vue 파일을 아무데나 만드신 후 그 안에 축약할 HTML을 붙여넣어줍니다.
.vue 파일은 항상 이런 형식으로 만드셔야합니다.
(예를 들면 Discount.vue)
<template>
축약할 HTML~~
</template>
<script>
export default {
name : '작명',
}
</script>
<style>
넣을 스타일
</style>
이 vue파일을 하나의 컴포넌트라고 부릅니다.
그 다음에 원하는 곳에서 어쩌구.vue 파일을
- import하고
- 등록하고
- 쓰면 됩니다.
그럼 길고 더러운 HTML을 깔끔하게 한 글자로 축약해서 적어넣을 수 있습니다.
참고로 name : 어쩌구로 작명도 가능합니다. 나중에 디버깅할 때 쓰는 이름입니다.
컴포넌트 쓰는 법
원하는 곳에서 어쩌구.vue 파일을
- import하고
- 등록하고
- 쓰면 됩니다.
import Discount from './Discount.vue 경로'
export default {
data() {
},
components : {
Discount,
}
}
아까 만들어둔 vue 파일을 import하고
등록하는건 위와 같이 script안에 작성해주면 됩니다.
components 라는 항목이 이미 있으면 그거 쓰시고 없으면 하나 만드십시오.
- 그럼 이제 template 안에서 자유롭게 가져다쓸 수 있습니다.
<Discount>
<Discount/>
이런 식으로 원하는 곳 아무데나 사용가능합니다.
Q. 복잡해보이는데 굳이 왜씀?
그냥 <div>여러개 있는거 보기싫으면 씁니다
다른 곳에서도 같은 HTML 재사용이 쉬워집니다. Vue 파일을 import하고 등록하고 쓰면 되니까요.
나중에 라우터로 페이지 구분하고 싶으면 하나의 페이지는 하나의 컴포넌트로 만드는게 좋습니다
모달창도 컴포넌트화 해봅시다
드디어 컴포넌트로 축약해볼 요소를 하나 찾은 것 같습니다.
전에 만들어놨던 모달창 코드는 매우 길고 복잡합니다.
이걸 쉽게 축약해봅시다.
Modal.vue를 만들고 직접 긴 HTML을 짧게 축약해보십시오.
다만 이렇게 쓰는 경우 문제가 있는데
- 모달창이 안열리는데요?
데이터바인딩할 때 문제가 생겨서 그렇습니다.
해결은 다음 강의에서 해봅시다.
그래서 대충 막 컴포넌트 100만개 만드시면 안됩니다.
코드가 복잡해질 수 있으니 각오하고 만드시면 됩니다.
부모가 가진 데이터를 자식이 쓰고 싶으면 props로 전해주자.
15분 숙제 :
예전에 상품목록을 6개 만들었는데 이것도 컴포넌트로 바꿔오십시오.
<Card/>
이렇게 바꾸는건 어떨까요.
근데 컴포넌트로 바꾸면 모달창여는 @click 코드가 고장날 수 있기 때문에 그 문제는 직접 해결해보도록 합시다.
이건 못해도 봐드림
저번 시간에
<Modal/>
컴포넌트를 만들어봤는데 모달창이 잘 안뜹니다.
데이터바인딩에 문제가 생겨서 그렇습니다.
모달창 만들어둔 Modal.vue 코드를 보시면..
<div class="black-bg" v-if="모달창열렸니 == true">
<div class="white-bg">
<img :src="원룸들[누른거].image" style="width:100%">
<h4></h4>
(생략)
대충 원룸들, 누른거 이런 변수를 데이터바인딩 잔뜩해놨는데
원룸들이라는 데이터가 Modal.vue안에 없어서 문제가 생긴겁니다.
(데이터바인딩 하려면 데이터가 밑에 있어야합니다)
그럼 어떻게합니까. 원룸들이라는 데이터를 Modal.vue 파일에도 복사 붙여넣기 해주면 되나요?
그건 안됩니다. 데이터를 사본을 만들기 시작하면 그 데이터가 업데이트사항이 생겼을 때 복사본들에 어떻게 전부 반영시킬겁니까.
미래를 생각해봤을 때 그건 하면 안될 짓입니다.
옳은 방법은 App.vue에 있던 원룸들이라고 저장해둔 데이터를 전송해서 쓰는 것입니다.
하위컴포넌트로 데이터를 전송하려면 props라는 문법으로 Modal.vue에 보내면 됩니다.
props 보내는 것도 3-step이 있습니다.
- 보내고
- 등록하고
- 써야합니다.
잠깐 용어정리를 하자면
App.vue 안에 Modal.vue를 집어넣어서 쓰고 있습니다.
이 경우 Modal은 하위 또는 자식 컴포넌트
App은 상위 또는 부모 컴포넌트라고 비유해서 부릅니다.
뭔가 새끼를 품고있는 것 같잖아요
자식이 부모가 가진 데이터 쓰려면 props
부모 -> 자식 이렇게 props라는 문법으로 전송해주어야 사용가능합니다.
props 쓰려면 이것도 3-step이 있습니다.
- 보내고
- 등록하고
- 쓰면 됩니다.
3번은 생략해도 에러는 안남
원룸들이라는 App.vue에 있는 데이터를 Modal.vue로 보내봅시다.
(App.vue)
<Modal :원룸들="원룸들" />
① 이렇게 데이터바인딩 문법쓰시면 데이터를 Modal로 보낼 수 있습니다.
<Modal :작명=”하단의데이터이름” /> 이런 식으로 써주면 됩니다. 근데 귀찮아서 이름 두개 통일함
(그래서 콜론 : 이거 역할은 2개입니다. 데이터바인딩 혹은 props 전송임)
(Modal.vue)
<script>
export default {
name : 'Modal',
props : {
원룸들 : Array,
}
}
</script>
② 자식컴포넌트는 데이터를 받으면 props로 등록하십시오.
props : {} 열고 거기다가 아까 작명한 { 데이터이름 : 자료형 }
적어주면 됩니다.
자료형엔 Array, Object, String, Number 이런 것들을 적으면 됩니다.
③ props 등록한 것들은 HTML안에서 데이터바인딩으로 자유롭게 사용가능합니다.
그래서 원룸들, 누른거, 모달창열렸니 이런 데이터들을 App.vue에서 Modal.vue로 한번 보내보십시오.
잘 보냈으면 모달창이 동작할겁니다.
하지만 닫기버튼은 주석처리합시다. 아마 props 수정하지마세요~ 이런 에러가 뜰겁니다.
props는 그냥 받아서 사용만 하는 read-only 데이터처럼 취급하셔야지 수정하시면 안됩니다. 에러남
Q. 애초에 Modal.vue에다가 원룸들, 누른거 이런거 데이터 저장해두면 안되나?
props가 귀찮기 때문에
App.vue에다가 만들지말고 애초에 Modal.vue 파일에다가 data(){} 열고
여기에 데이터들 저장해놓고 쓰면 안되냐는 소리입니다.
내가 이 데이터를 Modal.vue 안에서만 쓸 거라고 자신하면 거기다가 만드셔도 됩니다.
하지만 데이터를 만들 때 원칙이 있는데
“데이터를 사용하는 컴포넌트들 중 최상위 컴포넌트에다가 데이터를 만들어놔야함”
이걸 지켜서 만들어주시길 바랍니다.
왜냐면 데이터는 위로 전송하는게 복잡하고 추적이 어렵기 때문입니다.
귀찮으면 그냥 모조리 App.vue에 저장해놓으셈 그것도 나쁘지 않습니다.
오늘의 교훈 :
컴포넌트로 많이 쪼개면 props 보내는거 귀찮으니까
만들기 전에 “만들면 이득이 있을까” 라는 생각을 해보고 만들도록 합시다.
props 나머지 내용 조금
props에 대한 자잘한 추가내용을 배워봅시다.
별건 아니고 props로 데이터를 전송할 때 굳이 밑에 있는 데이터가 아니라도
문자, 숫자, array object 자료도 직접 집어넣을 수 있습니다.
props 보내는 여러가지 방법
<Discount :데이터이름="[1,2,3]" />
<Discount :데이터이름="{ age:20 }" />
<Discount :데이터이름="100" />
<Discount 데이터이름="안녕하쇼" />
각각 array, object, 숫자, 문자보내기입니다.
콜론을 안붙이면 문자로 전달됩니다.
오브젝트 : {name : 'kim', age : 20}
이라는 object 자료가 밑에 있는데
이걸 name, age 각각 props로 보내고 싶으면
<Discount :데이터이름="오브젝트.name" :데이터이름="오브젝트.age" />
이런 식으로 적어야하는데 이게 너무 번거로우면
<Discount v-bind="오브젝트명" />
이런 식의 특별한 문법을 사용해도 다 보내집니다.
근데 이러지말고 애초에 그냥 object 자료 통째로 보내면 되지않습니까.
저번시간 숙제 : 상품목록을 컴포넌트화하기
① 저는 Card.vue 부터 만들었습니다.
(Card.vue)
<template>
<div>
<img :src="a.image" class="room-img">
<h4> </h4>
<p> 원</p>
</div>
</template>
(밑엔 생략) v-for까지 넣어서 상품 6개를 전부
저는 상품 한개만
님들은 아무렇게나 하십시오 그냥 취향입니다.
그리고 모달창 여는 기능은 나중에 할거라 잠깐 지웠습니다.
그리고 App.vue에서 import하고 등록하고 사용했습니다.
<Card/>
import Card from './Card.vue'
export default {
components : {
Card
}
}
하지만 아무것도 안나오는 이유는 당연히
Card.vue 안에 a.title 이런게 있던데 a라는 변수엔 아무것도 없기 때문입니다.
a가 뭐였죠? 반복문 돌릴 때 나오는 그 하나하나의 상품데이터자료 아니었습니까.
그걸 props로 전송해주면 이제 제대로 상품명, 상품가격 이런게 나오겠군요.
② a에 필요한 정보를 props로 보내줍니다.
이전시간에 a는 반복문돌릴 때 나온 하나하나의 상품데이터라고 했습니다.
원룸들 : [ {}, {}, {}, {}, {}, {} ] 이거 안에 있던 하나의 {} 데이터요.
이걸 그대로 똑같이 props로 보내주면 되겠군요.
(App.vue)
<Card :원룸="원룸들[0]" />
저는 이쁘게 원룸이라고 작성해서 {} 이거 하나를 보내봤습니다. 첫째상품 데이터겠네요.
그리고 props를 보냈으면 등록하고 위에서 쓰셔야합니다.
(Card.vue)
<template>
<div>
<img :src="원룸.image" class="room-img">
<h4> </h4>
<p> 원</p>
</div>
</template>
<script>
export default {
props : {
원룸 : Object
}
}
</script>
원룸이라는 이름으로 props를 보냈으니까
데이터바인딩할 때도 대신 어쩌구 해주면 되겠군요.
이러면 Card가 첫째 상품으로 잘 이쁘게 보입니다. 끝
그럼 나머지 5개의 상품도 알아서 만들어보십시오.
Card 여기에 반복문 돌려도 됩니다. 반복문도 연습삼아 써보십시오
자식이 부모데이터 바꾸고 싶으면 custom event 로 메시지만 주자
5분 숙제 :
모달창 닫기버튼과 기능을 다시 만들어오십시오.
누르면 닫혀야합니다. 데이터를 어떻게 변경하면 모달창 닫히는지 다시 생각해봅시다.
자식컴포넌트가 부모가 가진 데이터를 바꾸고 싶어할 때가 있습니다.
하지만 그럴 순 없습니다. 애초에 다른 파일에 있는 거잖아요 그래서 못바꿈
그리고 props로 전해준 데이터도 변경하시면 안됩니다. 변경하게 되면 많은 부작용이 일어나서 일부러 Vue 자체에서 변경 불가능하게 막아두기도 했습니다.
그래서 부모가 가진 데이터를 바꾸고 싶으면 자식컴포넌트는 부모에게 메세지를 줘야합니다.
“부모야 저거 데이터 좀 바꿔줘” 이렇게 메세지를 주는겁니다.
부모는 그 메세지를 수신하면 데이터를 변경하는 코드를 짜놓으면 됩니다.
이걸 custom event 문법이라고 합니다.
custom event 문법을 이용한 부모가 가진 데이터변경방법을 요약하자면
자식은 $emit(작명, 전달할자료) 이렇게 부모에게 메세지를 보낼 수 있습니다. 부모까지 자료를 전달하고 싶으면 선택적으로 기입가능합니다.
부모는 @작명=”데이터변경하는JS코드” 이렇게 메세지를 수신해서 원하는 데이터를 변경하도록 코드를 짭니다. 끝
귀찮죠? 그러니까 컴포넌트 만들 때 이런걸 감수할 이유가 있어야한다니까요.
제목 누르면 모달창 여는 기능 고치기
Card.vue 안에 상품제목이 있습니다.
상품제목 누르면 모달창이 열리게 만들고 싶어서 다음과 같이 코드를 작성했습니다.
(Card.vue)
<template>
<div>
<img :src="a.image" class="room-img">
<h4 @click="모달창열렸니 = true"> </h4>
<p> 원</p>
</div>
</template>
근데 안됩니다. 왜냐면 모달창열렸니는 App.vue 부모가 가지고 있는 데이터니까요.
부모가 가진 데이터를 변경하고 싶으면 자식은 부모에게 부탁만 할 수 있습니다. 예의바르게요
부탁하는 법은 $emit(‘작명’, 전달할자료) 이 코드를 실행하면 됩니다.
$emit 이건 Vue가 제공하는 특별한 함수인데 ‘부모에게 부탁하는’ 함수입니다.
부탁이라고 비유했지만 실은 전문용어로 ‘커스텀 이벤트 전송’임
(Card.vue)
<template>
<div>
<img :src="a.image" class="room-img">
<h4 @click="$emit('openModal')"> </h4>
<p> 원</p>
</div>
</template>
아무튼 이렇게 쓰시면 제목을 눌렀을 때 부모 컴포넌트에게 부탁하게 됩니다.
(실은 openModal이라는 이름으로 커스텀 이벤트를 전송하는 겁니다.)
그럼 부모인 App.vue는 부탁을 받으면 데이터를 수정하면 됩니다.
모달창열렸니 = true 라고 해주면 모달창 열리니까 그렇게 합시다.
(App.vue)
<Card @openModal="모달창열렸니 = true" />
이렇게 쓰면 부탁을 수신할 수 있습니다.
(실은 자식이 보낸 커스텀 이벤트를 수신하는 코드입니다)
아무튼 이제 상품제목을 누르면 부모에게 $emit으로 부탁하고
부모는 부탁이 들어오면 모달창열렸니를 true로 바꿔줍니다. 그럼 모달창 열리네요 끝
근데 다른 상품 눌러도 왜 똑같은 모달창만 열리는 겁니까?
커스텀 이벤트로 부모에게 자료 보내는 법
당연히 예전에 모달창열 때
@click=”모달창열렸니 = true; 누른거 = 1
이런 식으로 코드를 짜야 잘 동작했기 때문입니다.
그래서 몇번 상품을 눌렀는지도 전달해서 App.vue에 저장해놔야합니다.
(Card.vue)
<template>
<div>
<img :src="a.image" class="room-img">
<h4 @click="$emit('openModal', 원룸.id)"> </h4>
<p> 원</p>
</div>
</template>
$emit()을 사용할 때 둘째 파라미터 자리에는 원하는 자료를 아무거나 입력가능합니다.
그럼 자료가 부모까지 전달이 됩니다.
그래서 원룸.id를 넣어봤습니다.
0번상품은 원룸.id가 0
1번상품은 원룸.id가 1이기 때문에
몇번 눌렀는지 잘 전달될듯요
부모는 $event라는 변수를 쓰면 그 보낸 자료가 담겨있습니다.
(App.vue)
<Card @openModal="모달창열렸니 = true; 누른거 = $event" />
아무튼 이렇게 해놓으면 예전과 똑같은 기능을 개발할 수 있겠군요.
그래서 요약하자면
자식이 부모 컴포넌트에 있는 데이터를 바꾸고 싶으면
custom event 문법으로 부탁을 하셔야합니다. $emit(작명, 전달할자료) 이렇게 사용합니다.
부모는 <자식컴포넌트 @작명=”부탁받으면할일”> 이렇게 해주면 됩니다.
- 밑에서 함수만들어서 사용하셔도 되는데
그럴 땐 this.$emit() 이라고 하셔야합니다.
사용자의 input을 받는 법 (v-model)
모달창 닫기버튼 만드는 저번시간 숙제는
<button @click="모달창열렸니 = false">닫기버튼</button>
Modal.vue에 이렇게 코드짜면 되겠습니까
모달창열렸니는 Modal.vue가 아니라 App.vue에 있는 데이터라 안됩니다.
부모에 있는 데이터 수정하고 싶으면 커스텀이벤트로 메세지를 주면 됩니다.
<button @click="$emit('closeModal')">닫기버튼</button>
그래서 Modal.vue는 이렇게 메세지를 보냈고
<Modal @closeModal="모달창열렸니 = false">
App.vue는 수신하는 코드를 이렇게 작성했습니다.
사용자가 input에 뭔가 입력하면 그걸 가지고 여러가지 UI 기능들을 만들어낼 수 있습니다.
쇼핑몰에서 흔히 쓰는
- 상품 수량변경기능
- 총금액계산기능
을 만들어보며 배워봅시다.
그러기 위해선 input에 유저가 입력한 내용을 data(){} 안에 저장하는 법 부터 알아야합니다.
실은 다 배우긴 했는데 @input @onchange 이벤트 핸들러 쓰셔도 되고
혹은 더 짧아보이는 v-model 이런거 쓰시면 됩니다.
사용자가 입력한 정보를 data로 저장하려면
그래서 Modal.vue에다가 input 하나만 만들어보십시오.
여기다가 상품 수량을 입력하면 수량에 맞는 최종가격을 모달창에서 보여주고 싶은겁니다.
코드 어떻게 짜야합니까.
사용자가 입력한 정보에 따라서 이것저것 뭔가 실시간으로 바뀌고 싶으면
당연히 data로 저장해두시고 필요할 때 하셔야합니다.
그래서 사용자가 에 입력한 값을 data로 저장하고 싶으면 코드 이렇게 짜면 됩니다.
(Modal.vue임)
<template>
(생략)
<input @input="month = $event.target.value">
</template>
<script>
export default {
data(){
return {
month : 0
}
}
}
</script>
@input 이거는 @click 이거랑 똑같은겁니다. 근데 사용자가 input에 뭔가 입력할 때 동작하는 이벤트핸들러입니다. 유사품 @change 이런 것도 있습니다.
$event는 Vue가 제공하는 특별한 변수인데 event object라는걸 뜻합니다.
자바스크립트 이벤트리스너에서 addEventListener(‘click’, function(e){}) 이런 문법을 쓰는데 여기서의 e랑 똑같은 의미입니다.
그래서 $event.target.value라고 작성하면 에 입력한 값을 가져올 수 있습니다.
- 그걸 밑에 month라는 data 항목에 저장하라고 써놨습니다.
그럼 이제 저기 에 뭔가 입력할 때마다 month라는 곳에 사용자가 입력한 값이 저장됩니다.
끝
Q. 그럼 사용자가 수량을 10이라고 입력하면 최종가격도 x10 해주려면 코드 어떻게 짜야하죠?
알아서 해보도록 합시다.
사용자가 입력한 정보를 data로 저장하려면 2
다른 방법도 있습니다. Vue는 뭔가 이런 자잘한 편의성 문법들이 많습니다.
<input @input="month = $event.target.value">
아까 이렇게 개발해 놓은걸
<input v-model="month">
이렇게 바꾸셔도 똑같이 동작합니다.
v-model은 “여기 입력된 값을 data로 바로 저장해주세요~” 라는 문법이기 때문입니다.
따옴표 안에 하단의 data 이름만 잘 적어주시면 됩니다.
(참고) 태그말고도 textarea select 이런 것들에도 전부 적용가능합니다.
input type=”checkbox” 등 타입을 다양하게 바꾸셔도 적용가능합니다.
(참고2) 사용자가 input에 적은건 무조건 문자입니다. 123이라고 적어도 ‘123’ 이런 문자로 저장됩니다.
그래서 v-model.number=”month” 이런 directive라는걸 사용하시면 숫자가 들어오면 숫자로 저장해줍니다.
하지만 숫자로 변환만 해주는 거지 ‘ㄱㄴㄷ’ 문자입력은 막을 수 없습니다.
막는건 다음시간에 해보도록 합시다.
watcher로 데이터 감시하는 법
5분 숙제 :
month라는 데이터 항목에 숫자가 아니라 문자가 들어오면
“숫자만 입력하라”는 alert()창을 띄워주고 month의 초기값을 1로 다시 설정해봅시다.
사용자가 input에 입력한 데이터는 무조건 문자입니다.
123 이렇게 입력해도 ‘123’ 이렇게 됩니다.
이걸 강제로 숫자로 바꾸고 싶으면 v-model.number=”데이터이름” 이것만 장착해주면
데이터로 저장될 때 숫자자료로 바꿔서 저장됩니다.
하지만 ‘abc’ 문자를 인풋에 입력하는걸 막을 순 없습니다.
이걸 막고 싶으면 watcher를 써봅시다.
watch : {} 라는 항목을 신설해서 거기다가 작성해주시면 되며
어떤 데이터를 계속 감시하는 역할을 하는 코드를 적을 수 있습니다.
감시한다는게 어려운건 아니고
그냥 특정 데이터가 변경될 때마다 실행되는 코드를 여기 적을 수 있습니다.
그게 감시죠 뭐
데이터를 감시하고 싶으면 watch
그래서 Modal.vue에 이렇게 작성해보십시오
export default {
data(){
return {
month : 1
}
},
watch : {
month(){
//month가 변경될 때 실행할 코드
}
}
}
watch 라는 항목에 감시자들을 만들 수 있습니다. 정해져있음
그리고 여기엔 함수를 집어넣을 수 있는데
함수명을 특이하게도 내가 감시하고 싶은 데이터명으로 작명하셔야합니다.
month() 이렇게 지으면 month 데이터 감시자가 되는 것임
그리고 그 함수안에 month가 변할 때마다 실행하고 싶은 코드를 적어주면 완성입니다.
참고로 month(a) 안에 파라미터 아무거나 작명해서 사용가능한데
그 파라미터는 month가 변경될 값을 의미합니다.
(두개까지 작명가능한데 첫째는 변경될 값, 둘째는 변경전 값을 의미합니다.)
Q. month 라는 데이터가 12보다 크게 변하면 경고문 띄우려면?
자바스크립트로 alert(‘안녕’) 이렇게 쓰면 경고문을 띄울 수 있습니다.
알아서 대충 짜보고 눌러보십쇼
if 라고 아십니까
export default {
data(){
return {
month : 1
}
},
watch : {
month(a){
if (a > 12) {
alert('13이상 입력하지마')
}
}
}
}
이외에도 검사해야할 경우가 많습니다
이메일 형식을 입력했는지
숫자나 문자만 입력했는지
비번에 영어 대문자가 들어있는지
이런 것들을 검사해야하는데 이건 정규식을 잘하시거나
아니면 체크할게 너무 많으면 Vue 용 form validation 라이브러리를 쓰기도 합니다. 찾아보도록 합시다.
오늘의 숙제 해설
month라는 데이터 항목에 숫자가 아니라 문자가 들어오면
“숫자만 입력하라”는 alert()창을 띄워주고 month의 초기값을 1로 다시 설정해봅시다.
이것은 답이지만 5시간 걸려도 직접 해보셔야합니다
구글신 님에게 물어봅시다.
자바스크립트로 이 자료가 숫자인지 아닌지 판단 어떻게 하는지요.
그랬더니 구글신이 답을 알려주네요
isNaN() 안에 숫자를 입력하면 false, 글자를 입력하면 true가 나온다고 합니다.
‘123’ 이런 숫자인척하는 글자도 false가 나온다고 하네요.
혹은 typeof 라는 키워드 옆에 자료를 입력하면 문자면 ‘string’ 숫자면 ‘number’ 이런 식의 문자가 남는다고 합니다.
둘 중 하나 쓰면 되겠군요.
근데 input에 입력한 데이터는 뭘해도 문자기 때문에 무조건 ‘string’ 자료가 나올 것 같군요
그래서 isNaN()이 더 유용해보입니다. (혹은 v-model.number를 활용하면 또 다를 수 있겠군요)
그래서 저는 month 감시자 안에 이렇게 코드 짤겁니다.
“month라는 데이터를 isNaN() 안에 집어넣어보고 true가 나오면 alert 띄우셈”
watch : {
month(a){
if (isNaN(a) == true){
alert('문자입력하지마라');
this.month = 1;
}
},
},
그랬다고 합니다. 그리고 문자를 입력한 경우에 month 초기값도 1로 설정해봤습니다.
하지만 스페이스바 입력같은 경우는 거를 수 없었다고 합니다.
이런건 알아서 해결해보십시오.
##Vue에서 매끈한 UI 애니메이션 주는 법 2개
UI가 등장시 퇴장시 애니메이션을 살짝 주고싶을 때가 있습니다.
방법은 2개가 있는데 그냥 CSS 애니메이션 주는 법을 이용해서 알아서 주든가 아니면
Vue가 제공하는 transition 태그를 이용해서 줄 수도 있습니다.
쌩 CSS로 애니메이션 주는 법은
애니메이션 시작 전 class를 디자인해놓고
애니메이션 동작 후 class를 디자인해놓습니다
그리고 원할 때 애니메이션 동작 후 class를 부착하면 됩니다. 예를 들면 모달창이 열릴 때요.
시작 전 class 명에 transition 속성을 주면 부드럽게 애니메이션이 완성됩니다.
이렇게 코드짤 땐 조건부로 class명을 부착하고 싶어질 수도 있습니다. 그럴 땐
<div :class="{ 클래스명 : true }"> </div>
이렇게 쓰면 됩니다. 오른쪽이 true 혹은 true 비슷한 자료일 때만 부착됩니다.
그래서 버튼을 누르면 저걸 true로 바꿔주든가 하시면 클래스가 부착되겠군요. (그래서 true 대신에 데이터명을 입력하고 그러시면 됩니다)
클래스가 부착되면 애니메이션이 실행되게 CSS를 잘 짜놓으면 애니메이션 완성입니다.
- Vue에서 제공하는
태그를 이용하려면
이건 지성이 필요없는 개발하고 싶을 때 사용합니다.
- 애니메이션 주고 싶은 UI를 ```
으로 감쌉니다.
2. CSS로 다음과 같이 스타일을 주면 됩니다.
.작명-enter-from { 애니메이션 동작 전 상태 }
.작명-enter-active { 애니메이션 동작 중 상태, 대부분 transition 이런거 }
.작명-enter-to { 애니메이션 동작 후 상태 }
그럼 UI가 등장시 애니메이션이 동작합니다.
퇴장시 애니메이션을 주고 싶으면 스타일에서 enter라는 글자를 leave 이걸로 바꾸면 됩니다.
그냥 쓰는 법을 Vue 문법으로 정해주기 때문에 나의 논리와 생각이 필요없는 무지성 개발이 가능합니다.
-------
## 상품정렬기능과 데이터 원본 보존
오늘의 혼자해볼 숙제 :
상품명 가나다순 정렬은 어떻게 할까요?
가격 역순 정렬은요?
50만원 이하의 상품만 보여주는 필터기능은요?
답은 없습니다 알아서 하도록 합시다.
버튼을 누르면 상품이 가격순으로 정렬되어 보이는 기능을 만들어봅시다.
버튼을 누르면 상품이 정렬되어서 보여야하는데 그럼 코드를 어떻게 짜야겠습니까.
하단에 있는 원룸들이라는 데이터가 있는데 그걸 가격순으로 정렬만 하면 됩니다.
원룸들이라는 데이터는 [ {}, {}, {}, {}, {}, {} ] 이렇게 생겼습니다.
{} 안에 각각 상품 정보들이 들어있고요. 이걸 가격순으로 정리하면 개발 끝입니다.
HTML은 어떻게 보일지 신경쓸 필요가 없습니다. 데이터를 정렬만 하면 알아서 바뀝니다.
을 잘 해두셨으면 데이터가 변경사항이 생길시 HTML에도 자동으로 실시간 반영된다고 했으니까요.
정렬버튼 만들고 기능을 부여해봅시다
App.vue에 버튼 하나 만들고 기능을 만들어봅시다.
<button @click=”priceSort()” >가격순정렬</button> methods : { priceSort(){ this.원룸들.sort() } }
이런 식으로 코드를 짜면 가격순 정렬을 구현할 수 있을 듯 한데
잠깐 자바스크립트 .sort() 함수에 대해 설명드리자면
var array = [2,5,1]; array.sort();
이렇게 쓰면 array 자료가 가나다 순으로 정렬됩니다.
var array = [2,5,1]; array.sort(function(a,b){ return a - b });
이렇게 쓰면 array 자료가 숫자 123 순으로 정렬됩니다.
왜냐면 a와 b라는 파라미터는 array 안에 있던 하나하나의 자료를 뜻한다고 보면 됩니다. 2랑 5 이런겁니다.
그리고 return 오른쪽에 있는 값이 - 음수면 a를 왼쪽,
양수면(+) a를 오른쪽으로 보내줍니다.
그런 원리로 sort 라는 함수가 동작하기 때문에 함수 안에 저렇게 코드를 이상하게 짜놓으면 숫자 123 순으로 정렬이 되는 것입니다. 오름차순 정렬이요.
321 순으로 내림차순 정렬하려면 코드 어떻게 짜야하게요? 알아서 할 수 있겠죠?
그럼 우리 프로젝트로 돌아가서
<button @click=”priceSort()” >가격순정렬</button> methods : { priceSort(){ this.원룸들.sort(function(a,b){ return a - b }) } }
this.원룸들이라는 자료는 어떻게 sort() 함수를 써야 가격순으로 정렬이 될까요.
원룸들이라는 자료는 [ {}, {}, {}, {}, {}, {} ] 이렇게 생겼습니다.
{} 안에 상품 하나의 이름, 가격 이런 것들이 잔뜩 들어있고요.
그래서 대충 return a - b 라고 기입하시면 안됩니다.
{} - {} 해봤자 음수든 양수든 아무것도 안나오기 때문입니다.
음수나 양수가 나오도록 return 오른쪽을 잘 개발해보시길 바랍니다.
순서 원래대로 되돌리기 버튼 만들고 기능을 부여해봅시다
App.vue에 원래대로 되돌리는 버튼도 추가하고 싶은 겁니다.
<button @click=”sortBack()” >되돌리기</button> methods : { sortBack(){ ??? } }
누르면 원래 순서대로 돌아와야하는데 이거 코드 어떻게 짜면 되는거죠?
방법은 여러개인데 일단 사본을 만들어서 원본을 보존하는 방법도 좋은 방법입니다.
포토샵으로 사진보정할 때도 사본 하나를 만들어서 보정하지 않습니까.
그래서 원룸들 data를 똑같은걸 두개 만들어두는 겁니다.
data(){ return { 원룸들오리지널 : data, 원룸들 : data } } methods : { sortBack(){ this.원룸들 = this.원룸들오리지널 } }
그래서 오리지널 원본을 똑같이 하나 만들어두고
되돌리기 버튼을 누르면 오리지널 원본을 가져와서 저기 집어넣는겁니다. 그럼 되겠네요
실은 안됩니다.
왜냐면 array나 object에다가 = 등호로 뭔가를 집어넣으시면
등호 왼쪽 오른쪽에 있는 array/object는 서로 값을 공유해주세요~ 라는 뜻이기 때문입니다.
왜 그런지는 reference data type을 찾아보도록 합시다.
그래서 아무튼 저렇게 sortBack()을 디자인해놓으면 안된다는 소리입니다.
data(){ return { 원룸들오리지널 : […data], 원룸들 : […data] } } methods : { sortBack(){ this.원룸들 = […this.원룸들오리지널] } }
그래서 우리가 array 자료를 복사하거나
아니면 값공유가 일어나지 않게 집어넣고 싶으면
[...array자료] 이렇게 사용합니다.
그래서 저렇게 온갖 곳에 다 사용해봤습니다.
그러면 안전하게 원본 array를 집어넣을 수 있습니다. 되돌리기 버튼 잘 동작할 듯요
점 3개 ... 문법 (spread operator) 에 대한 내용
가끔 자료의 사본을 만들고 싶을 때가 있습니다.
가장 쉽게 복사할 수 있는 방법이 등호를 사용하는 겁니다.
예를 들면 a에 있던 자료를 b로 복사하고 싶으면
var a = ‘안녕하세요’; var b = a;
이렇게 등호를 사용합니다.
등호는 오른쪽에 있던걸 대입하라는 뜻이니까요. 그럼 a와 b는 둘다 안녕하세요가 되겠네요.
근데 array,object 자료를 등호로 복사하면 큰일납니다.
var a = [1,2,3]; var b = a;
이렇게 등호를 사용하면 자료의 사본을 만들어주라는 뜻이 아닙니다.
a와 b가 [1,2,3] 이걸 공유하라는 뜻입니다.
그니까 이제 b를 수정하면 a에도 변경사항이 반영됩니다.
object도 저렇게 복사하면 똑같은 현상이 일어납니다.
그래서 강의에서처럼 this.원룸들 = this.원룸들오리지널 이런거 하시면
"오리지널데이터를 저기 집어넣어라~"라는 뜻이 아니라
"원룸들 & 원룸들오리지널은 서로 값을 똑같이 공유해주세요~" 라는 뜻입니다.
그래서 이 상태에서 원룸들.sort()를 하시면 원룸들도 정렬되고 원룸들오리지널도 정렬됩니다.
그래서 오리지널 데이터를 제대로 보존할 수 없습니다.
그래서 값공유가 일어나지않게 독립적인 array 복사본을 만들고 싶으면
var a = [1,2,3]; var b = […a];
이렇게 하시면 됩니다.
. . . 이 기호는 spread operator 라는 신기한 문법인데
array나 object 앞에 붙일 수 있으며
array, object의 괄호를 제거해주는 문법입니다.
그래서 . . . [1,2,3] 이런 식으로 쓰면 1,2,3만 남는다는 소리입니다.
그래서 약간의 트릭인데 array를 복사할 때 spread operator 이걸로 괄호를 벗겼다가 다시 씌우면
그런 값공유 현상이 일어나지않게 복사할 수 있습니다.
array를 해체했다가 다시 array로 만들면 서로 값 공유하지않는 별개의 사본을 만들 수 있어서 그렇습니다.
일종의 편법입니다.
왜 그냥 복사하면 값공유가 일어나는지는 심심하면 reference data type 을 찾아보도록 합시다.
-----
## Vue의 라이프사이클을 어디다 쓰는가.
오늘의 숙제 1.
메인페이지 방문하자마자 30%라고 적힌 할인 문구가
1초마다 1%씩 감소하려면? (setInterval() 이런거 필요할 수도)
오늘의 숙제 2.
모달창 내에 input이 있는데 여기에 2를 기입했을 때 알림창 alert() 을 띄우려면?
물론 watcher를 쓰면 되는데 이거 말고 오늘 배운 lifecycle hook을 이용합시다.
힌트는 데이터가 변경되면 HTML (컴포넌트)가 재렌더링되는데 이걸 라이프사이클 용어로 update라고 합니다.
![20220105_013913](/assets/20220105_013913.png)
뷰 공식문서 살펴보다보면 Lifecycle 이라고 설명하는 이상한 부분이 있습니다.
대충 컴포넌트는 이런 step으로 생성되고 사라지고 업데이트 된다는 소리인데
이걸 왜 설명하고 있냐면 Lifecycle hook 이란걸 쓰기 위해서입니다.
1. 컴포넌트를 보여줄 때 create -> mount 이 단계로 생성됩니다.
create는 데이터생성, mount는 index.html 파일에 장착 이렇게 생각하시면 됩니다.
2. 데이터가 바뀌어서 컴포넌트가 재렌더링될 때는 update 단계를 거치며
3. 다른페이지로 이동하거나 그럴 때 컴포넌트가 삭제될 때는 unmount 라는 단계를 거칩니다.
이 단계들 중간중간에 코드를 실행시키고 싶을 때가 있습니다.
예를 들면 mount 되기 전에 뭔가 ajax 요청으로 서버에서 데이터를 가져오거나
update 되기 전에 뭔가 코드를 실행해서 데이터를 검증해보거나
이런 식입니다.
그럴 때 lifecycle hook을 골라서 쓰면 됩니다.
beforeCreate() created() beforeMount() mounted() beforeUpdate() updated() beforeUnmount() unmounted()
대충 이렇게 있습니다. 함수명만 잘 읽어봐도 어떤 기능을 하는 함수인지 알 수 있겠군요.
예를 들어서 beforeUpdate() 이건 언제 쓰는 함수겠습니까.
컴포넌트가 update되기 전에 뭔가 실행시키고 싶을 때 쓰는 함수입니다.
예를 들어서 mounted() 이건 언제쓰는 함수겠습니까.
컴포넌트가 mount 되고 나서 뭔가 실행시키고 싶을 때 쓰는 함수입니다.
data(){ return {
} }, mounted(){ 어쩌구~ }
대충 컴포넌트 파일 하단에 저런 식으로 쓰면 됩니다. 그럼 mount가 되고나서 어쩌구~라는 코드를 실행해줍니다.
특히 서버가 있으면 서버에서 데이터 가져오는 일이 잦은데
데이터가져오는 코드를 mounted() 아니면 created() 여기에 보통 작성합니다.
1.
메인페이지 방문하자마자 30%라고 적힌 할인 문구가
1초마다 1%씩 감소하려면? (setInterval() 이런거 필요할 수도)
이건 쉬우니까 답 펼쳐보면 쪽팔림
일단 App.vue에 할인해주는 문구를 p태그로 하나 만들어보겠습니다.
원래는 Discount가 있지만 약간 이해를 돕기 위해서 새로 만들겁니다.
그 안에 30% 이런 수치가 있으면 데이터로 만들어서
왜 데이터로 만들어서 하냐고요? 자주변하는 데이터는 그렇게 하라고 배웠던 기억이 납니다.
그래서 역시 문법만 외우면 되는게 아니라 이 문법을 언제 왜 쓰는지를 함께 배워야합니다.
(App.vue)
지금 결제하면 % 할인
(App.vue 하단 데이터만드는 곳) data(){ return { amount : 30, } }
그럼 이제 페이지 로드시 저 30이라는 숫자를 1초마다 1씩 감소시켜야합니다.
그건 setInterval() 이라는 자바스크립트 내장 함수 이용하면 된다고 했습니다.
그리고 페이지 로드시 실행해야하니까 mounted()안에 넣으면 되겠군요.
(App.vue 하단)
mounted(){ setInterval(()=>{ this.amount–; }, 1000); }
이러면 끝입니다.
직접 해볼 응용 :
- 계속 감소하는게 아니라 숫자가 0 밑으로 안떨어지게 하려면? (0이 되면 타이머 삭제)
- Discount 컴포넌트를 이용하려면?
이것은 알아서 해보도록 합시다.
2.
모달창 내에 input이 있는데 여기에 2를 기입했을 때 알림창 alert() 을 띄우려면?
물론 watcher를 쓰면 되는데 이거 말고 오늘 배운 lifecycle hook을 이용합시다.
힌트는 데이터가 변경되면 HTML (컴포넌트)가 재렌더링되는데 이걸 라이프사이클 용어로 update라고 합니다.
이것도 쉬우니까 답 펼쳐보면 쪽팔림
지금 모달창 내의 input에 뭔가 입력하면 HTML이 자동으로 재렌더링 됩니다.
이걸 라이프사이클 용어로 표현하면 Modal 컴포넌트가 update 되는겁니다.
일부분만 바뀌는 것 같지만 Modal이 전부 재렌더링 된다고 보시면 됩니다. 원래 그럼
그래서 update 되기 전에 뭔가 실행하고 싶어서
Modal.vue 안에다가 라이프사이클 훅을 걸어볼겁니다.
beforeUpdate(){ if (this.month == 2){ alert(‘2개월은 너무 적음.. 안팝니다’) } } ```
▲ 업데이트 되기 전에 month라는 데이터를 검사하는겁니다. 그리고 그 데이터가 2면 뭔가 원하는 동작을 실행시켜주는 코드입니다.
직접 해볼 응용 :
- 2라는걸 입력하면 이걸 3이나 4로 강제로 바꿔버리는건 어떨까요.