Fly higher! Sky is the limit!

webの現場で働く人のブログ

【脱jQuery】YouTubeから取得したプレイリスト(JSON)をVue.jsで表示してみた。

「昔作ったサイトをVue.jsで書き換えています。」的な記事をチラホラみかけるので私も勉強がてらに実装してみました。
※ 本記事では、YouTubeからプレイリスト(JSON)を取得するところの説明は省いております。
(ググれば優秀な記事がたくさん出てくるので…)

jQueryでつくったサンプル

https://codepen.io/takumaro-web/pen/dNepxr

今回はこちらのソースをVueに書き換えていきます。

jQueryすっぞ。

XHRライブラリは、「ajax」の代わりに「axios」を使用します。
Vue.jsの公式ページでもオススメしているのでこちらでよいかと思います。

axios.get('https://www.googleapis.com/youtube/v3/playlistItems', {
    params: {
      part: 'snippet',
      playlistId: '******************************', /*Youtubeのplaylist id*/
      maxResults: 9, /*表示する動画の数*/
      key: '******************************' /*アクセストークンを指定*/
    }
  })
  .then(function 

(response) {
    initVue(response.data.items);
  })
  .catch(function 

(error) {
    console.log(error);
  });

こんな感じで取得完了!
直感的で結構シンプル!Angularの$httpっぽい!

さっそくVueで書き換えていく。

htmlから書き換えていく。

手順1:生成させたいhtmlをとりあえずかく。

テンプレート的なものになるので完成形をイメージしながらそれっぽくかく。
ポイントは、とりあえずVueで処理するところは{{ }}でかこっておく。

<ul id="list">
  <li>
    <a href="{{}}" >
      <img src="{{}}">
      <span class="title">{{ }}</span>
      <span class="des">{{ }}</span>
    </a>
  </li>
</ul>

手順2: Vueで操作するhtmlをかきかえていく。

  • li がループされていい感じに表示されればよいから「v-for」を使う。
  • v-for を使うときに後々、「何番目の要素が押されたか?」的な話になるので「(item,index) in items」で指定する。
  • とりあえず、aタグにはv-on:clickを指定し動画を選択できるようなイメージをもたせておく。
  • hrefとsrcは、v-bindで指定しないと動かないのでこちらを指定しておく。
  • テキストは{{ JSONの中身 }}を指定しておく。
<ul id="list">
  <li v-for="(item,index) in items">
    <a v-on:click="movieDetail(index)" v-

bind:href="item.snippet.resourceId.videoId" >
      <img v-bind:src="item.snippet.thumbnails.high.url">
      <span class="title">{{ item.snippet.title }}</span>
      <span class="des">{{item.snippet.description }}</span>
    </a>
  </li>
</ul>

これでなから(※)html側の準備は完了しました。
※ なから:地元長野の方言で大体という意味。

手順3: Vue.jsをつかってjsをかいていく。

  • ターゲットとなる要素を指定し、dataには配列(items)を指定する。
  • これでインスタンスが生成されたのでcreatedフックで、取得したデータ分だけfor文でまわしデータを格納していく。
  • methodsを使用し、data(this)にアクセスする。
    ※ 今回は、methodsの中身は生のJavaScriptを記述してみました。
  • JavaScriptの記述に合わせて、htmlも多少修正。
  function initVue(moveInfo){
    var vm = new Vue({
      el: "#list",
      data: {
        items:[]
      },
      created: function(){
          for(var i = 0; i < moveInfo.length; i++){
             this.items.push(moveInfo[i]);
          }
      },
      methods: {
        movieDetail: function (index) {
          var videoId = this.items[index].snippet.resourceId.videoId;
          var title = this.items[index].snippet.title;
          
          var mainVideoElem = document.querySelector('#main-video');
          
          //削除処理
          var move = document.querySelector('iframe');
          var moveTitleElem = document.querySelector('#moveTitle');
          mainVideoElem.removeChild(move);
          
          //追加処理
          var iframe = document.createElement('iframe');
          iframe.src = 'https://www.youtube.com/embed/'+ videoId +'?rel=0';
          iframe.width = "600";
          iframe.height = "315";
          mainVideoElem.appendChild(iframe);
          moveTitleElem.innerHTML = title;
        }
      }
    });
  }

感想「とりあえず動くものが完成!!」

https://codepen.io/takumaro-web/pen/owgbMm

探り探りな部分もありましたが、なんとか形になりました。 methodsの中身ももしかしたら、もっとうまいことできるのかもしれません…。 やりたい事は明確なのに、記述方法がわからないということが多々あったので今後はこの辺を勉強していきたいです。

アドバイスがある方は、是非コメントくださいませ。