vue.js

axios응용

코딩 화이팅 2023. 5. 12. 15:59

유투브 영상들을 검색하고 검색한 썸네일을 출력하기

YoutubeView.vue
<template>
  <div>
    <h2>유튜브 전용페이지</h2>
    <youtube-search></youtube-search>
    <hr />
    <youtube-search-result></youtube-search-result>
  </div>
</template>

<script>
import YoutubeSearch from "../components/youtube/YoutubeSearch.vue";
import YoutubeSearchResult from "../components/youtube/YoutubeSearchResult.vue";

export default {
  name: "YoutubeView",
  components: {
    YoutubeSearch,
    YoutubeSearchResult,
  },
};
</script>

<style scoped>
h2 {
  color: red;
}
</style>
==============================================================
index.js
import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    videos: [],
    video: null,
  },
  getters: {},
  mutations: {
    SEARCH_YOUTUBE(state, videos) {
      state.videos = videos;
    },
  },
  actions: {
    //비동기 통신은 요기서 진행시켜~~
    searchYoutube({ commit }, payload) {
      const URL = "https://www.googleapis.com/youtube/v3/search";
      const API_KEY = process.env.VUE_APP_YOUTUBE_API_KEY;
      axios({
        url: URL,
        method: "GET",
        params: {
          key: API_KEY,
          part: "snippet",
          q: payload,
          type: "video",
          maxResults: 10,
        },
      })
        .then((res) => {
          commit("SEARCH_YOUTUBE", res.data.items);
        })
        .catch((err) => console.log(err));
    },
  },
  // modules: {
  // }
});
==============================================================
YoutubeSearchResult.vue
<template>
  <div>
    <h3>검색 결과</h3>
    <ul class="youtube-list">
      <youtube-video-item
        v-for="video in videos"
        :key="video.id.videoId"
        :video="video"
      ></youtube-video-item>
    </ul>
  </div>
</template>

<script>
import { mapState } from 'vuex';
import YoutubeVideoItem from './YoutubeVideoItem.vue';

export default {
  components: { YoutubeVideoItem },
  name: 'YoutubeSearchResult',
  computed: {
    ...mapState(['videos']),
  },
};
</script>

<style scoped>
.youtube-list {
  text-align: left;
}
</style>

올라온 영상들을 누르면 객체 불러 영상 불러오기

YoutubeVideoItem.vue
<template>
  <li @click="clickVideo">
    <img :src="video.snippet.thumbnails.default.url" />
    {{ video.snippet.title }}
  </li>
</template>

<script>
export default {
  name: "YoutubeVideoItem",
  props: {
    video: {
      type: Object,
      required: true,
    },
  },
  methods: {
    clickVideo() {
      this.$store.dispatch("clickVideo", this.video);
    },
  },
};
</script>

<style></style>
===============================================================
index.js
import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    videos: [],
    video: null,
  },
  getters: {},
  mutations: {
    SEARCH_YOUTUBE(state, videos) {
      state.videos = videos;
    },
    CLICK_VIDEO(state, video) {
      state.video = video;
    },
  },
  actions: {
    //비동기 통신은 요기서 진행시켜~~
    searchYoutube({ commit }, payload) {
      const URL = "https://www.googleapis.com/youtube/v3/search";
      const API_KEY = process.env.VUE_APP_YOUTUBE_API_KEY;
      axios({
        url: URL,
        method: "GET",
        params: {
          key: API_KEY,
          part: "snippet",
          q: payload,
          type: "video",
          maxResults: 10,
        },
      })
        .then((res) => {
          commit("SEARCH_YOUTUBE", res.data.items);
        })
        .catch((err) => console.log(err));
    },
    //payload : 비디오 객체가 들어온다.
    clickVideo({ commit }, payload) {
      commit("CLICK_VIDEO", payload);
    },
  },
  // modules: {
  // }
});
===============================================================
YoutubeViewDetail.vue
<template>
  <div v-if="video">
    <!-- 비디오가 있어야만! -->
    <h2>영상 보기!</h2>
    <!-- 유투브에 더보기에 iframe을 복붙 -->
    <iframe
      width="560"
      height="315"
      :src="videoURL"
      title="YouTube video player"
      frameborder="0"
      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
      allowfullscreen
    ></iframe>
  </div>
</template>

<script>
import { mapState } from "vuex";
export default {
  name: "YoutubeVideoDetail",
  computed: {
    ...mapState(["video"]),
    videoURL() {
      const videoId = this.video.id.videoId;
      return `https://www.youtube.com/embed/${videoId}`;
    },
  },
};
</script>

<style></style>