-
[Vue.js] v-model, watcher, TransitionFront-End/Vue.js 2022. 11. 24. 16:17
📑 v-model 값 이용하기
사용자의 입력값 받으려면 v-model을 사용한다. 예를들어 원룸을 판매하는 어플이 있을 때 몇 개월을 살지 입력하면 그에 맞는 가격이 출력되도록!
<!--input은 숫자로 입력해도 자료형은 문자열로 나올 것이다. html요소.addEventListener('click',function(e){}) 여기서 e가 $event와 같은 것 . @input은 사용자가 입력할 때마다 month라는 곳에 값을 입력해줘라.--> <!-- <input @input="month= $event.target.value"> --> <!--v-model은 input, select, textarea 등등 다 가능--> <input v-model.number="month"> <p> {{month}} 개월 선택함 : {{외부데이터[사용자클릭].price * month}}</p>
v-model을 안 쓴다면, @input 이벤트를 통해 사용자가 값을 입력하면 month라는 변수에 $event.target.value 사용자가 입력한 값을 받아오게 만들었다. 그 후 {{ }} 데이터 바인딩을 통해 {{month}}의 값을 출력한다.
만약 데이터 바인딩을 하려면 data()에 month라는 데이터를 선언해줘야한다. 초기값을 1로 출력한다. input 태그에 값이 들어오면 string 형태로 저장되는데 이를 숫자로 변환하기 위해 v-model.number를 해준다. number를 붙여주면 숫자 뒤에 붙는 문자는 무시하게 된다 '1ㅇㄹㅈㄷ' 이러면 '1'만 인식하게 된다.
export default { name : 'Modal', data(){ return{ month :1, } }, //data(){}로 만들면 되지 않음? //되긴 되는데 부모도 쓰는 데이터라면 부모컴포넌트에 만들어두자. props : { 외부데이터 : Array, 모달창보이나 : Boolean, 사용자클릭 : Number, } }
📑 watcher : 데이터 감시자
만약 숫자를 입력해야되는 input 태그 값에 문자가 들어온다면? 그때 사용하는게 watcher이다. 함수 명을 감시하는 데이터 이름과 같게하면 된다. 위에서 month는 사용자의 입력을 받아오는 input 태그에 model 값으로 받아뒀다.
<input v-model="month"> <p> {{month}} 개월 선택함 : {{외부데이터[사용자클릭].price * month}}</p>
model이라는 데이터가 변할 때 watch는 아래 정해둔 조건값에 해당한다면 alert를 실행한다.
watch :{ //month를 감시하는 함수인 것. 이름은 데이터 이름과 같게 하면 된다. month(a){ //사용자가 month를 글자로 입력하면 경고문 띄워주셈 if(a>=13) { alert(' 13보다 작아야 됩니다 경고경고!'); this.month=1; }else if(isNaN(a)==true ){ //숫자가 아니라면 alert('숫자만 입력하세요'); this.month=1; } } },
📑 애니메이션 주기 Transition
UI가 등장하고 퇴장할 때 애니메이션을 주는 방법은 2가지가 있다. 하나는 CSS 애니메이션을 주는 방법이고 다른 하나는 Vue가 제공하는 <Transition> 태그를 이용해서 줄 수도 있다.
일단 css로 애니메이션을 주려면 1. 시작전 class 디자인 2. 끝난 후 class 디자인 3. 원할 때 2번 클래스를 부착
📌 1. css 애니메이션 주기
<div class="start" :class="{ end : 모달창보이나}">
위와 같이 class명에 start라는 이름을 주고 end는 만약 "모달창보이나"라는 데이터가 true가 된다면 부착되게 만들었다. css 스타일은 아래와같이 주면 된다. 그럼 모달창이 떴을 때 희미하게 보였다가 서서히 선명해지는 걸 확인할 수 있다.
.start{ opacity: 0; /*이 클래스에 있는 애니메이션 변할 때 1초에 걸려 스무스하게 변한다.*/ transition : all 1s; } .end{ opacity: 1; }
📌 2. Vue에서 제공하는 <Transition> 태그 이용
트랜지션을 적용하고 싶은 문장을 <Transition> 태그로 감싼다. 그후 name 값으로 명칭을 지정해주면 된다.
<Transition name="fade"> <!-- <div class="start" :class="{ end : 모달창보이나}"> --> <Modal @closeButton ="모달창보이나=false;" :외부데이터="외부데이터" :사용자클릭="사용자클릭" :모달창보이나="모달창보이나"/> </Transition>
명칭을 fade로 준 뒤 from, active, to에 주고 싶은 속성을 주면 된다.
/*시작스타일*/ .fade-enter-from{ transform: translateY(-1000px); opacity :0; } .fade-enter-active{ transition: all 1s; } /*끝 스타일*/ .fade-enter-to{ transform: translateY(0px); opacity :1; }
📑 정렬 sort()
array.sort()는 문자정렬이다. 배열안의 문자들은 문자순으로 정렬해주는 것. 만약 숫자순으로 정렬하고 싶다면 아래와 같이 사용한다.
var array = [3,5,2];
array.sort(function(a,b){
return a-b; //a-b가 만약 양수면 숫자를 오른쪽으로 보낸다.
});sort는 근데 원본을 영구적으로 변경한다. 그렇기에 다시 정렬했던 걸 되돌리려면 어떻게 할까?? 원본 데이터를 보존해두는 방법이 있다.
array와 object는 a=b와 같은 등호를 사용하면 갑을 집어넣으라는 의미가 아닌 a와 b의 값을 공유해줘. 라는 의미이다. 따라서 되돌리기를 하려고 this.원룸들 = this.원룸원본데이터 이런식으로 등호를 사용하면 문제가 생긴다.
여기서 값 공유가 일어나지 않게 독립적인 array 복사본을 만들고 싶다면 ... 이 기호를 사용하자. 이 기호는 spread operator라는 기호로 array, object의 괄호를 없애주는 문법이다. 만약 ...[1,2,3]을 쓴다면 1,2,3 이렇게 쓰인다는 소리이다.
<!--vue의 html과 같은 뼈대, App.vue에다가 작성한다. --> <template> <!-- 동적인 UI 만드는 법 1. UI의 현재 상태를 데이터로 저장해둔다. 2. 데이터에 따라 UI가 어떻게보일지 작성한다. 3. --> <!--props로 자식에게 데이터 보내는 법 1. 데이터 보내고 2. 등록하고 3. 쓰면 된다. --> <Modal :원룸들="원룸들" :모달창열렸니="모달창열렸니" :사용자가누른상품번호="사용자가누른상품번호" @closeModal="모달창열렸니=false"></Modal> <div class="menu"> <!-- <a>Home</a> <a>Products</a> <a>Sale</a> --> <!-- <a v-for="작명 in 반복횟수">Home</a> --> <a v-for="a in 메뉴들" :key="a">{{a}}</a> </div> <Discount></Discount> <button @click="priceSort()">가격순정렬</button> <button @click="sortBack()">되돌리기</button> <Card @openModal="모달창열렸니=true; 사용자가누른상품번호=$event" :원룸들 = "원룸들[i]" v-for="(a,i) in 원룸들" :key="a"></Card> </template> <script> //document.getElementById().innerHTML = ?? ; 기존 JS에서는 이렇게 해야 값을 집어넣을 수 있엇다. 하지만 뷰에서는 이렇게 길게 코드를 짜지 않는다. /* 데이터 바인딩 하는 이유는 ? 1. HTML에 하드코딩해놓으면 나중에 변경이 어렵다. 2. VUE의 실시간 자동 렌더링을 하려고 실시간으로 바뀔 데이터가 아니라면 그냥 하드코딩 해도 된다. 3. HTML 속성도 데이터 바인딩이 가능한데 그건 v-on을 사용해서 바인딩 한다. */ import data from './assets/data.js'; import Discount from './Discount.vue'; import Modal from './Modal.vue'; import Card from './Card.vue'; export default { name: 'App', data(){ return{ price1 : 60, price2 : 70, 스타일 : 'color : red' , products : ['역삼동원룸', '천호동원룸','용현동원룸'], 메뉴들 : ['HOME', 'SHOP','ABOUT'], num :[0,0,0], 모달창열렸니 : false, //UI가 어떻게 보일지 현재 상태를 기록 원룸들 : data, 원룸들오리지널 :[...data], 사용자가누른상품번호 : 0 } }, methods: { increase(){ this.신고수+=1; }, priceSort(){ //아래와 같음 문자 정렬이다. 정확한 숫자는 function을 넣어야된다. /* this.원룸들.sort() */ this.원룸들.sort(function(a,b){ return a.price-b.price }) }, sortBack(){ //sort는 원본을 아예 변형시켜버린다. 따라서 원본을 보존하려면 map, filter 이용해야한다. this.원룸들 = [...this.원룸들오리지널]; } }, components: { Discount : Discount, Modal, Card } } </script> <style> 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; } #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } .menu { background: darkslateblue; padding : 15px; border-radius: 5px; } .menu a{ color:white; padding: 10px; } .room-image{ width:100%; } </style>
반응형'Front-End > Vue.js' 카테고리의 다른 글
[WEB] SPA(Single Page Application)이란? (0) 2023.02.02 [Vue.js] Vue의 라이프사이클 (create, mounte, update, destroy) (0) 2022.11.25 [Vue.js] import/export, component 사용해보기 (0) 2022.11.23 [Vue.js] npm 방식 vue 기본 문법 (on:click, v-html, v-for, 데이터바인딩 ,,) (0) 2022.11.22 [Vue] Vue.js npm 방식으로 설치하기 , VSCode 프로젝트 생성 (0) 2022.11.21