본문 바로가기

FrontEnd/Vue

[Frontend] VanillaJS vs Vue.js (4)

Vue



Vue의 패턴은 MVVM패턴이다.


Controller의 역할을 ViewModel이 한다.


FormComponent


index.html

<form v-on:submit.prevent="onSubmit">
<input type="text" v-model="query" v-on:keyup="onKeyup"
placeholder="검색어를 입력하세요" autofocus>
<button v-show="query.length" v-on:click="onReset" type="reset"
class="btn-reset"></button>
</form>


Vue는 Html에서 View의 역할을 한다.(세상에나)

Model의 데이터를 받거나 이벤트를 발생시키는 것들이..

하나씩 살펴보면

<form>

v-on

v-on : submit.prevent=Vue객체의 메소드


특정 돔 이벤트를 지정하고 돔 이벤트가 발생시에 Vue객체의 메소드를 실행시킨다.

addEventListener나 on(돔이벤트)의 역할을 함


위 같은 경우에는

폼 태그의 submit이벤트 발생시에

preventDefault()를 발동하고

Vue 객체의 onSubmit()을 실행시킨다.


<input>

V-model

v-model = Vue객체의 프로퍼티 data의 프로퍼티

Vue객체의 데이터(모델)과 바인딩 시키는 역할을 한다.

v-on:keyup
인풋에 키보드입력시마다 onKeyup()실행

<button>

v-show

v-show="query.length"

Boolean타입을 받으며
결과가 True일때는 display가 show로
아닐 시에는 hide가 됨

v-on:click="onReset"

index.html
<div v-if="submitted">
<div v-if="searchResult.length">
<ul>
<li v-for="item in searchResult">
<img v-bind:src="item.image"> {{item.name}}
</li>
</ul>
</div>
<div v-else>
{{query}} 검색어로 찾을수 없습니다
</div>
</div>

폼태그 아래의 SearchResult부분

v-if

Boolean타입을 받으며
True일시에만 해당 태그가 존재함

v-if="submitted"
검색어가 제출되었을때만 아래 div가 존재

v-if="searchResult.length"
검색 결과가 존재 할 때만 해당 div가 존재
아닐시에는
v-else의 div가 존재 

v-for

배열타입을 받고 태그를 반복해서 생성
v-for="item in searchResult"
searchResult의 모든 배열인자들을 item으로 정의하고 반복 실행

{{Model}}

모델을 불러낼 때


이에 따른 속성들은 각각 이러함
app.js
import SearchModel from './models/SearchModel.js'

new Vue({
el: '#app',
data: {
query: '',
submitted: false,
searchResult: []
},
methods: {
onSubmit(e) {
this.search()
},
onKeyup(e) {
if (!this.query.length) this.resetForm()
},
onReset(e) {
this.resetForm()
},
search() {
SearchModel.list().then(data => {
this.submitted = true
this.searchResult = data
})
},
resetForm() {
this.query = ''
this.searchResult = []
this.submitted= false
}
}
})

Vue객체를 생성후에 파라미터로

1.el <= 적용할 element (이 때 자식 노드들까지 모두 적용됨)

2. data

3.methods


data


query

 input의 value를 컨트롤 하기 위해 사용할 예정


submitted

제출 전 후를 컨트롤 하기 위해서 사용

searchResult

모델에서 데이터를 담을 배열


methods


onSubmit()

Form의 submit시 실행되는 함수

search()를 실행


serach()

SearchModel.list().then(...)

모델에서 Promise 함수로 받은 데이터를

seachResult에 담음

(이는 곧 렌더링 하기 위함)


onKeyup()

query가 비었을 때(input의 value가 없을 때)

resetForm()실행


onReset()

리셋버튼 클릭시에 

resetForm()실행


resetForm()

this.query를 초기화 하고(input의 value)

this.searchResult를 초기화하고(렌더링할 요소를 없애고)

this.submitted을 false로 전환(검색하기 이전)


TapComponent


<div v-else>
<ul class=tabs>
<li
v-for="tab in tabs"
v-bind:class="{active: tab == selectedTab}"
v-on:click="onClickTab(tab)"
>
{{tab}}
</li>
</ul>
<div v-if="selectedTab === tabs[0]">
추천 검색어 목록
</div>
<div v-else>
최근 검색어 목록
</div>
</div>


검색어가 없을 시에 실행


v-for

vue속성키중 tabs배열을 차례로 가져와 li태그 생성


v-bind:class

class를 사용하는데 vue 키가 필요해서 사용

tab이 selectedTab과 같은 경우의 li태그는 active로 클래스를 바꿈


v-on:click

onClickTab(tab)을 실행

파라미터는

타겟의 벨류값 


onClickTab(tab){
this.selectedTab = tab


onClickTab은

this.selectedTab을 바꿈


KeywordComponent

<div v-if="selectedTab === tabs[0]">
<div v-if="keywords.length">
<ul class="list">
<li
v-for="(item,index) in keywords"
v-on:click="onClickKeyword(item.keyword)"
>
<span class="number">{{index+1}}</span>
{{item.keyword}}
</li>
</ul>
</div>


keywords의 length가 존재 할 경우에

ul태그를 실행


v-for="(item,index) in keywords"

v-for에 index를 위와 같은 방식으로 추가할 수 있음


fetchKeyword(){
KeywordModel.list().then(data => {
this.keywords = data
},


모델의 데이터를 받음


HistoryComponent


<div v-if="historys.length">
<ul class="list">
<li v-for="(item, index) in historys"
v-on:click="onClickHistory(item.keyword)">
<span class="number">{{index + 1}}</span> {{item.keyword}}
<span class="date">{{item.date}}</span>
<button class="btn-remove" v-on:click.stop="OnClickRemoveHistory(item.keyword)" >
</button>
</li>
</ul>
</div>


v-on:click.stop


button은 li태그 자식태그라서 이벤트 버블링이 생긴다(onClickHistory도 실행)


보통은

stopPropagation()메소드를 이용하지만

Vue에서는 .stop으로 버블링을 해결한다.