npm install -g @vue/cli
vue create 프로젝트이름
npm run serve
vue-cli 설치, 프로젝트 생성, 런 서버
npm i axios
npm i lodash
axios, lodash를 사용하기 위해 다운받는다.
Google Cloud console
console.cloud.google.com
youtube data api 키를 발급받는다.
컴포넌트 구성은 이와 같다.
App - SearchBar, VideoDetail, VideoList(VideoListItem)
<template>
<div id="app">
<h1>TUBE</h1>
<SearchBar/>
<VideoDetail/>
<VideoList/>
</div>
</template>
<script>
import SearchBar from '@/components/SearchBar'
import VideoList from '@/components/VideoList'
import VideoDetail from '@/components/VideoDetail'
export default {
name: 'App',
components: {
SearchBar,
VideoList,
VideoDetail
}
}
</script>
App.vue
App의 하위 컴포넌트를 불러와서 등록, 사용했다.
<template>
<div>
<input type="text" v-model="search">
<button @click="searchVideo">검색</button>
</div>
</template>
<script>
import axios from 'axios'
const API_KEY = process.env.VUE_APP_YOUTUBE_API_KEY
export default {
name: 'SearchBar',
data:function(){
return{
search : null,
}
},
methods : {
searchVideo(){
console.log('hello')
axios({
method:'get',
url:'https://www.googleapis.com/youtube/v3/search',
params : {
part : 'snippet',
type : 'video',
q : this.search,
key : API_KEY
}
})
.then((response)=>{
this.$emit('search-video',response.data.items)
this.search=''
})
}
}
};
</script>
<style>
</style>
SearchBar.vue
input, button태그가 있다. input 입력값은 v-model으로 데이터 연결을 해준다. (v-model="search")
버튼을 클릭하면 searchVideo라는 메서드를 실행하도록 했다.
searchVideo메서드에서 axios를 이용해서 api 데이터를 불러오려고 한다.
const API_KEY = process.env.VUE_APP_YOUTUBE_API_KEY
.env.local 이라는 파일에 api key를 변수에 담아두었다.
이것을 이용하기 위해 process.env.변수명 으로 가져왔다.
axios({
method:'get',
url:'https://www.googleapis.com/youtube/v3/search',
params : {
part : 'snippet',
type : 'video',
q : this.search,
key : API_KEY
}
})
이렇게 파라미터들은 params에 담아서 url, method와 함께 가져올 수 있다.
axios({
method:'get',
url:`https://www.googleapis.com/youtube/v3/search?key=${API_KEY}&part=snippet&type=video&q=${this.search}`,
})
한번에 url에 백틱``과 ${}변수를 이용할 수도 있다.
.then((response)=>{
this.$emit('search-video',response.data.items)
this.search=''
})
axios로 데이터를 가져오면 response.data.items를 emit해준다.
emit이름은 search-video로 했다. emit했기 때문에 SearchBar.vue의 부모컴포넌트인 App.vue에서 받을 수 있게 된다.
<SearchBar @search-video = "search"/>
App.vue
search-video(emit)을 받아오면 search 메서드를 실행한다.
export default {
name: 'App',
components: {
SearchBar,
VideoList,
VideoDetail
},
data : function(){
return{
videolist : [],
}
},
methods : {
search(videolist){
this.videolist = videolist
},
}
}
search메서드는 emit할때 보내주었던 response.data.items를 인자로 받는다.
videolist라는 data를 만들고 저장해주었다.
<VideoList :videolist="videolist"/>
이 데이터를 VideoList에 보내준다.
<template>
<ul>
<VideoListItem
v-for="(video, index) in videolist"
:key="index"
:video="video"
/>
</ul>
</template>
<script>
import VideoListItem from "@/components/VideoListItem";
export default {
name: "VideoList",
components: {
VideoListItem,
},
props: {
videolist: Object,
},
};
</script>
VideoList.vue
VideoListItem을 하위컴포넌트로 가지고 있기 때문에 불러오고 등록하고 사용한다.
App에서 받아온 VideoList를 props에 등록한다.
이는 Object이기 때문에 v-for으로 요소 하나씩 가져오도록 한다.
요소를 하나씩 video라고 하고, video라는 파라미터를 통해 자식 요소에게 보내준다.
<template>
<div @click = "select">
<img :src="video.snippet.thumbnails.high.url" alt="">
<p>{{video.snippet.title}}</p>
</div>
</template>
<script>
export default {
name : "VideoListItem",
props : {
video : Object
},
methods : {
select : function(){
this.$emit('select',this.video)
}
}
}
</script>
VideoListItem.vue
VideoList에서 받아온 video를 props에 등록한다.
제목을 보여주기 위해 video.snippet.title을 {{}}에 감싸 출력하고, 썸네일을 img 태그에 넣어준다.
리스트 아이템 요소를 클릭하면 동영상을 보여주도록 하기 위해 @click="select"로 클릭하면 select 메서드가 실행되도록 했다. 이 메서드는 this.video 비디오 요소를 emit해준다.
emit 이름은 select이다.
<template>
<ul>
<VideoListItem
v-for="(video, index) in videolist"
:key="index"
@select="select"
:video="video"
/>
</ul>
</template>
<script>
import VideoListItem from "@/components/VideoListItem";
export default {
name: "VideoList",
components: {
VideoListItem,
},
props: {
videolist: Object,
},
methods : {
select : function(video){
this.$emit('select',video)
}
}
};
</script>
VideoList.vue
@select = "select"
emit으로 select를 인식하면 select메서드를 실행한다. 이 메서드는 select emit을 보내고, 받아온 데이터를 그대로 video라는 이름으로 보내게 된다.
<template>
<div id="app">
<h1>TUBE</h1>
<SearchBar @search-video = "search"/>
<VideoDetail :video = "video" />
<VideoList @select = "select" :videolist="videolist"/>
</div>
</template>
<script>
import SearchBar from '@/components/SearchBar'
import VideoList from '@/components/VideoList'
import VideoDetail from '@/components/VideoDetail'
export default {
name: 'App',
components: {
SearchBar,
VideoList,
VideoDetail
},
data : function(){
return{
videolist : [],
video : '',
}
},
methods : {
search(videolist){
this.videolist = videolist
},
select(video){
this.video = video
}
}
}
</script>
App.vue
select emit을 받아오면 select 메서드를 실행한다.
video라는 변수를 만들어서 받아온 video 데이터를 저장한다.
이 video 변수를 VideoDetail에 보내주기 위해 video라는 이름의 파라미터를 이용한다. :video="video"
<template>
<div>
<iframe id="player" type="text/html" width="640" height="360"
:src="`http://www.youtube.com/embed/${video.id.videoId}`"></iframe>
</div>
</template>
<script>
export default {
name : "VideoDetail",
props : {
video : Object,
},
}
</script>
<style>
</style>
VideoDetail.vue
받아온 video 파라미터에 담긴 데이터를 props에 등록한다.
이를 이용해서 iframe 태그에 넣어주면 동영상이 보인다.
'Front-end > Vue.js' 카테고리의 다른 글
Lifecycle Hooks - created, mounted, updated, destroyed (0) | 2022.11.07 |
---|---|
Vuex state management - store : state, actions, mutations, getters (0) | 2022.11.07 |
데이터 흐름 : pass props / emit event (0) | 2022.11.02 |
Vue CLI / Module / Vue 프로젝트, 컴포넌트 생성 (0) | 2022.11.02 |
computed, method 비교 / watch / filters (0) | 2022.10.31 |