LoginSignup
1
4

More than 5 years have passed since last update.

Vue.js で 配列とJSONの切り替え表示を行う

Last updated at Posted at 2018-12-25

Vue.js で調べたいことがあったのでメモがてら。

やりたいこと

Vue.jsで、ユーザーの操作に合わせてデータの増減や表示の切り替えをしたい。
テストシナリオとして、以下の3つを試してみる

  • アクセスカウンタ
    • ユーザーの操作で数字が増減する
  • 表示切り替え
    • ユーザーの操作で配列内のデータを切り替えて表示
  • REST API のデータの表示切り替え
    • REST API経由で取得したデータを切り替えて表示

アクセスカウンタの実装

Vue.js でアクセスカウンタを実装する方法は、公式ドキュメント「イベントハンドリング」に書いている。

v-on ディレクティブを使うことで、DOM イベントの購読、イベント発火時の JavaScript の実行を行う。

以下は、簡単なアクセスカウンタの例。
こちらの記事を参考にしました。 元記事では Node.js を利用していますが、今回は1枚のhtmlに書き直しています。

Vue.js はCDNから読み込んでいます。

Vue.js のインスタンス「vm」を生成。vmに変数「count」を初期値0として定義。countはリアクティブな状態にして、v-on ディレクティブで変数countに対し増減を行う。

<!DOCTYPE html>
<html lang="ja">
<head>
  <title>Vue.js でカウンター練習</title>
  <meta charset="utf-8">
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>

<h1>Vue.js でカウンターの練習</h1>

<div id="counter">
  <div>{{count}}</div>

    <button v-on:click="decrement">-1</button>
    <button v-on:click="increment">+1</button>
</div>

<script>
  "use strict";
  const vm = new Vue({
    el: '#counter',
    data() {
      return {
        count: 0
      }
    },
    methods: {
      increment() {
        this.count++
      },
      decrement() {
        this.count--
      }
    }
  });

</script>

</body>
</html>

実際に動くサンプルはこちら。
https://codepen.io/TakeshiNickOsanai/pen/jXwrWL

配列の中身をVue.js で切り替える

さきほどのアクセスカウンタを少しアレンジ。

  • 配列に格納されている文字列を「次へ」「前へ」のボタンクリックで切り替えながら表示する。
  • 配列内のデータを、増減する変数「count」をキーとして取得、レンダリングする。

アクセスカウンタでは、無限に数字を増減できた。

今回のシナリオでは、配列に格納されたデータを上限として、表示のコントロールをする必要がある。そこで配列の中身をlengthで取得し、数字に上限を設けた。

同様に、0以下にはデクリメントできないように修正した。

<!DOCTYPE html>
<html lang="ja">
<head>
  <title>Vue.js で配列の中身を切り替えながら表示する練習</title>
  <meta charset="utf-8">
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>

<h1>Vue.js で配列の中身を切り替えながら表示</h1>

<div id="counter">
  <div>{{arr[count]}}</div>

    <button v-on:click="decrement">前へ</button>
    <button v-on:click="increment">次へ</button>
</div>
  <script>

  "use strict";

   const vm = new Vue({
     el: '#counter',
     data () {
       return {
         arr : ['apple', 'orange', 'strawberry'],
         count: 0
       }
     },

  methods: {
      increment(){
        if (this.count < this.arr.length -1 ){
          this.count++;
        }
      },
      decrement() {
        if(this.count > 0) {
        this.count--
      }
    }
  }
  });
</script>

</body>
</html>

実際に動くサンプルはこちら

上記の例では、Vueインスタンス内のdataオブジェクトにあらかじめ配列を格納した。

下記は、先に中身が空のオブジェクト「arr」を生成。リアクティブな状態で待受を行い、あとで配列を格納する書き方。動作は上記と同じ。

<!DOCTYPE html>
<html lang="ja">
<head>
  <title>Vue.js で配列の中身を切り替えながら表示する練習</title>
  <meta charset="utf-8">
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>

<h1>Vue.js で配列の中身を切り替えながら表示</h1>

<div id="counter">
  <div>{{arr[count]}}</div>

    <button v-on:click="decrement">前へ</button>
    <button v-on:click="increment">次へ</button>
</div>

<script>
  "use strict";
  const vm = new Vue({
    el: '#counter',
    data() {
      return {
        arr: '',
        count: 0,
      }
    },
    methods: {
      increment() {
        if (this.count < this.arr.length - 1) {
          this.count++;
        }
      },
      decrement() {
        if (this.count > 0) {
          this.count--
        }
      }
    }
  });
  // Vueインスタンス生成後、配列「arr」にデータを追加
  vm.arr = ['apple', 'orange', 'strawberry'];
</script>

</body>
</html>

実際に動くサンプルはこちら

REST APIからデータを取得し、切り替えながら表示を行う

もう少しアレンジを加えて、以下のようなことをやってみる。

  • REST APIからJSONデータを取得
    • 今回は作家「古川日出男」さんの書籍データを、Google Books APIから取得する
  • 書籍データのJSONから、書籍名を配列に格納
  • ユーザーの操作で、書籍名を切り替えながら表示

Google Books API から取得したJSONデータをループ処理して、タイトルだけをVMインスタンス内の配列「arr」にPUSHしていく。あとは配列のサンプルと同じ。

API経由でデータを取得してからレンダリングを行うために、Promise で非同期処理を行う。
REST APIとの通信は、axiosを使いました。

<!DOCTYPE html>
<html lang="ja">
<head>
  <title>Vue.js でREST APIから取得したデータの切り替え練習</title>
  <meta charset="utf-8">
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>

<h1>古川日出男の著作一覧</h1>

<div id="counter">
  <div>{{arr[count]}}</div>

    <button v-on:click="decrement">前へ</button>
    <button v-on:click="increment">次へ</button>
</div>
<script>
  "use strict";
  const list = axios('https://www.googleapis.com/books/v1/volumes?q=%E5%8F%A4%E5%B7%9D%E6%97%A5%E5%87%BA%E7%94%B7');
  const vm = new Vue({
    el: '#counter',
    data() {
      return {
        arr: [],
        count: 0,
      }
    },
    methods: {
      increment() {
        if (this.count < this.arr.length - 1) {
          this.count++;
        }
      },
      decrement() {
        if (this.count > 0) {
          this.count--
        }
      }
    }
  });
  Promise.resolve(list).then(function(response) {
    for (let i in response.data.items) {
      vm.arr.push(response.data.items[i].volumeInfo.title);
    }
  });
</script>

</body>
</html>

動作するサンプルはこちら

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4