<template>
<input v-model="title" />
<button @click="searchMovies">
Search!
</button>
<ul>
<li
v-for="movie in movies"
:key="movie.ImdbID">
<img
:src="movie.Poster"
alt=""
height="40" />
{{ movie.Title }}
</li>
</ul>
<button
//movie.length가 있는 경우 버튼이 화면에 출력
v-if="movies.length"
@click="searchMoviesMore">
More...
</button>
</template>
<script>
export default {
data() {
return {
title:'',
page:1,
movies:[]
}
},
methods: {
async searchMovies() {
this.page=1
let res=await fetch(`https://www.omdbapi.com?apikey=7035c60c&s=${this.title}&page=${this.page}`)
res = await res.json()
const { Search, totalResults } = res
this.movies = Search
this.page=2
},
async searchMoviesMore() {
let res = await fetch(`https://www.omdbapi.com?apikey=7035c60c&s=${this.title}&page=${this.page}`)
res = await res.json()
const { Search, totalResults } = res
this.movies.push(...Search)
this.page += 1
}
}
}
</script>
methods: {
async searchMovies() {
console.log(isFirst)
if(isFirst) {
//밑에서 push로 밀어넣기 위해서 빈배열로 초기화
this.movies = []
this.page=1
}
let res=await fetch(`https://www.omdbapi.com?apikey=7035c60c&s=${this.title}&page=${this.page}`)
res = await res.json()
const { Search, totalResults } = res
this.movies.push(...Search)
this.page += 1
}
클릭이 일어났을 때 클릭 이벤트를 인수로 넣어주기 때문에 isFirst는 무조건 truthy가 되게 됩니다.
따라서 click버튼을 실행하는 경우 바로 searchMovies함수가 실행되도록 다음과 같이 작성을 힐 스 있습니다.
<input v-model="title" />
//실행을 시킴
<button @click="searchMovies()">
Search!
</button>
즉, vue.js에서는 함수의 이름만 연결을 해도 되지만 어떤 인수를 받아 메소드를 실행시키는 경우에는 ()를 통해 받을 인수를 설정해줄 수 있습니다.
따라서 아래와 같이 Search버튼 클릭시 실행시킬 searchMovies함수에는 true를 인수로 넣어줍니다.
<template>
<input v-model="title" />
<button @click="searchMovies(true)">
Search!
</button>
<ul>
<li
v-for="movie in movies"
:key="movie.ImdbID">
<img
:src="movie.Poster"
alt=""
height="40" />
{{ movie.Title }}
</li>
</ul>
<button
v-if="movies.length"
@click="searchMovies()">
More...
</button>
</template>
이렇게 작성을 해주면 한 함수를 사용하면서도 만약 다른 타이틀 값을 검색하는 경우 초기화가 되게 실행을 할 수 있습니다.
v-on이벤트에 enter수식언을 붙여 작성하면 됩니다.
<input
v-model="title"
@keydown.enter="searchMovies(true)" />
디렉티브
-v-model, v-for, v-bind, v-if 등
computed속성을 이용해 위의 res.data 중 필요한 데이터만 뽑아내어 사용할 이름을 설정해보도록 하겠습니다.
앞서, 클래스를 다시 상기시켜보도록 하겠습니다.
class Name {
constructor(first, last) {
this.first = first
this.last = last
}
fullName() {
return `${this.first} ${this.last}`
}
}
위와 같이 정의된 함수에서 fullName을 얻기 위해서는 아래와 같이 호출을 했어야했습니다.
const n = new Name('Heropy', 'Park')
console.log(n.fullName())✅
하지만 fullName메소드 앞에 get을 붙이는 경우 함수처럼 호출하지 않아도 사용을 할 수 있었습니다.
class Name {
constructor(first, last) {
this.first = first
this.last = last
}
get fullName() {✅
return `${this.first} ${this.last}`
}
}
const n = new Name('Heropy', 'Park')
console.log(n.fullName)✅
즉, 사용을 할 때는 데이터처럼 사용을 하지만 실제로 fullName은 함수이었습니다.
이와 유사하게 computed에 정의된 메소드도 get이라는 키워드를 붙이지 않을 뿐이지 내부에서는 getter와 동일하게 작동을 합니다.
즉, 값을 얻는 용도의 함수지만 데이터처럼 사용이 됩니다.
computed: {
//Getter
customMovies(){
//this.movies를 통해 원본 데이터를 가져옵니다(⭐원본데이터는 필수입니다)
return this.movies.map(movie => {
return {
//사용할 데이터를 뽑아 원하는 이름으로 정의를 해줍니다.
poster: movie.Poster,
title: movie.Title,
id: movie.imdbID
}
})
}
},
이렇게 계산한 데이터는 아래와 같이 사용할 수 있습니다.
<ul>
<li
v-for="movie in customMovies"
:key="movie.id">
<img
:src="movie.poster"
alt=""
height="40" />
{{ movie.title }}
</li>
</ul>
보관법을 통해 methode를 사용할 때는 ()를 통해 호출해줘야합니다.
<template>
<h2>{{ msg }}</h2>
<h2>{{ reverseMsg() }}</h2>
<h2>{{ reverseMsg() }}</h2>
<h2>{{ reverseMsg() }}</h2>
<h3>{{ reversedMsg }}</h3>
<h3>{{ reversedMsg }}</h3>
<h3>{{ reversedMsg }}</h3>
</template>
<script>
export default {
data() {
return {
msg: 'HEROPY?!'
}
},
computed: {
reversedMsg() {
return this.msg.split('').reverse().join('')
}
},
methods: {
reverseMsg() {
return this.msg.split('').reverse().join('')
}
},
}
</script>
computed로 만든 데이터의 경우 캐싱이 되기 때문에 여러번 재사용을 하더라도 캐싱된 데이터를 통해 바로 화면에 출력이 됩니다. 즉, 계산은 1번만 하게 됩니다.
하지만, method의 경우 사용할 때마다 호출이 되게 됩니다. 즉 계산이 호출하는 횟수만큼 하게 됩니다.
따라서 출력되는 데이터는 똑같더라도 반복 사용되는 경우 computed를 사용하면 조금 더 효율적입니다.
computed속성의 setter(값을 지정할 때 실행되는 함수)를 사용할 수도 있습니다.setter의 경우 vuex를 사용할 때 효율적으로 사용할 수 있습니다.
<h2>{{ msg }}</h2>
<h3>{{ reversedMsg }}</h3>
<button @click="reversedMsg=123456">
Set!!
</button>
reversedMsg: {
get() { //Getter
return this.msg.split('').reverse().join('')
},
set(newvalue) { //Setter
console.log('computed Setter', newvalue)
}
}
data, computed 등 반응형 데이터를 감시하는 용도로 사용되는 속성이 바로 watch입니다.
watch: {
movies(newValue, oldValue) {
console.log('new', newValue)
console.log('old', oldValue)
}
영화를 검색하게 되면, 아래와 같이 확인을 할 수 있습니다.
이렇게 watch속성을 이용해 어떠한 데이터가 바뀌면 처리를 하는 로직을 작성할 수 있습니다.