プログラミング

3択クイズゲーム作成で悩んだVue.jsでのclassの削除

Vue.jsで3択クイズゲーム!今回は、ドットインストールのJavaScript講座にある3択クイズゲームをVue.jsで作って見ました! ドット...

 

Vue.jsで3択クイズゲームを作ってて、いくつか悩んだところがあったんですけど、そのうちの1つがclassの削除でした。

 

 

 

どのような処理がしたかったかというと、

 

 

  • li要素の中で、選択された要素が正解だった場合はcorrect、間違っていた場合はwrong classを付ける
  • 次の問題に行くときは、付けたclassは全部削除する

 

 

 

という処理でした。で、悩んだんですけど、結局自分ではどうすることもできなくて、初めてteratailというサービスを使いました。これは、質問をするとそれに対してわかる方がなんと無料で答えてくれるサービスです。

 

 

 

初めて使いましたが、1時間もしないうちに回答してくれた方がいて、すぐに解決しました!本当に感謝しています。

 

 

 

 

教えてもらった処理内容のキモは以下のような感じです。

 

 

<HTML>

<ul v-on:click="select">
  <li v-for="(element,index) in elements" 
      v-bind:class="{correct:clickedIndex === index}">
    {{ element }} 
  </li> 
</ul>

 

  • v-onでクリックイベントを付けておく
  • v-bindでcorrectクラスを付ける。クラスを付ける条件はclickedIndexとindexが同じとき。

 

 

<Vue.js>

select(e){ 
  this.clickedIndex = [...e.currentTarget.children].indexOf(e.target); 
},

 

  • currentTarget.childrenでulの子要素liを取得
  • indexOfで選択されたliの番号を取得

 

 

 

という感じでした。clickedIndexがキモでしたね。

 

 

 

ちなみに、この部分

[...e.currentTarget.children]

 

 

コンソールログにこのようにして出力させて見るとわかりますが、上の方はHTMLCollectionという型のようです。そのままではindexOfで子要素の番号を取れないので、… を追加して配列に展開してるみたいですね!ちなみに、… のところはスプレッド演算子というので覚えておきましょう!

console.log(e.currentTarget.children);
console.log([...e.currentTarget.children])

 

 

 

 

全体のコードは以下になります。

 

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>class remove</title>
</head>
<body>

  <div id = "app">
    <ul v-on:click="select">
      <li v-for="(element,index) in elements"
          v-bind:class="{correct:clickedIndex === index}">
        {{ element }}
      </li>
    </ul>
    <div v-on:click="next">next</div>
  </div>
  
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script>
    (function(){
      'use strict';

      var vm   = new  Vue({
        el:'#app',
        data(){
          return {
            elements:['a1', 'a2'],
            clickedIndex:null,
          }
        },
        methods:{
          select(e){
            this.clickedIndex = [...e.currentTarget.children].indexOf(e.target);
          },
          next(e){
            this.clickedIndex=null;
          },
        }
      });
    })();
  </script>
</body>
</html>

 

 

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です