4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue.js + Vuetify + Project-ShangriLa でアニメ情報を取得するアプリ作成

Last updated at Posted at 2019-05-01

目的

面白いAPIを見つけたのでせっかくだからWebアプリ作ってみよう

環境

Windows Subsystem for Linux
OS: Ubuntu

使用技術

Vue.js(SPAフレームワーク)
Vuetify(UIコンポーネントライブラリ)
axios(Ajax通信ライブラリ)
materialdesignicons(マテリアルデザインアイコン)

サーバーレス+小規模なアプリなのでいかに低コストで導入できるかで選びました
(ちょっとVue使ってみたかった感もある)

やったこと

プロジェクト作成

$ vue create animecheck

Vuetify追加

オプション指定などできるけどデフォルトを指定する

$ vue add vuetify

マテリアルデザインアイコン用のパッケージインストール

$ npm install @mdi/font --save
$ npm install material-design-iconfont --save

選択用コンボボックス作成

2014年~現在までの西暦とクールを選択する用のコンボボックスを作成する

search.vue
<template src="../view/search.html">
</template>

<script src="../js/search.js">
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped src="../assets/css/search.css">
</style>

html, js, css それぞれ別々に書いたほうがわかりやすそうだったので、vueファイルはテンプレートのみ記載する

search.html
    <v-layout row wrap>
        <v-flex xs12 sm6>
            <v-overflow-btn v-model="year" label='年' :items="selectYear" @change="getAnime"></v-overflow-btn>
        </v-flex>
        <v-flex xs12 sm6>
            <v-overflow-btn v-model="season" label='クール(季節)' :items="selectSeason" @change="getAnime"></v-overflow-btn>
        </v-flex>
    </v-layout>

:items でコンボボックスに入れる選択値を設定する
選択された値は v-model で指定している year, season にそれぞれ入る

search.js
import axios from 'axios';
import 'vuetify/dist/vuetify.min.css'
import '@mdi/font/css/materialdesignicons.css'
import 'material-design-icons-iconfont/dist/material-design-icons.css'

export default {
    data() {
        return {
            year: '',
            season: '',
            animes: [],
            selectYear: this.getYear(),
            selectSeason: [
                {value: '1', text: '冬 (1 ~ 3 月)'},
                {value: '2', text: '春 (4 ~ 6 月)'},
                {value: '3', text: '夏 (7 ~ 9 月)'},
                {value: '4', text: '秋 (10 ~ 12 月)'},
            ]
        }
    },
    methods: {
        /**
         * 2014 ~ 現在までの年数を取得する関数
         */
        getYear: function() {
            let currentYear = (new Date()).getFullYear();
            const baseYear = 2014;
            let years = []
            while(currentYear >= baseYear) {
                years.push({value: currentYear, text: currentYear + ''})
                currentYear -= 1;
            }
            return years
        },
    }
...
}

クールだけは面倒なので固定で書いてしまった
(固定値として別の場所に書きたい)

アニメ取得APIとの連携

西暦とクールを選択したら、APIにリクエストを送りレスポンスをいい感じに加工して画面に表示する

search.html
    <v-layout v-if="animes.length" row wrap>
        <v-flex lg4 sm12 xs12 v-for="anime in animes">
            <v-card raised tile class="grey lighten-3 ma-2">
                <v-card-title primary-title>
                    <div>
                        <div class="headline">
                            {{ anime.title }}
                        </div>
                    </div>
                </v-card-title>
                <v-divider light></v-divider>
                <v-card-actions class="pa-3">
                    <v-btn flat>
                        <a v-bind:href="anime.public_url">
                            <v-icon>
                                mdi-laptop
                            </v-icon>
                        </a>
                    </v-btn>
                    <v-btn flat>
                        <a v-bind:href="'https://twitter.com/' + anime.twitter_account">
                            <v-icon>
                                mdi-twitter
                            </v-icon>
                        </a>
                    </v-btn>
                    <v-btn flat>
                        <a v-bind:href="'https://twitter.com/search?q=%23' + anime.twitter_hash_tag + '&src=typd'">
                            <v-icon>
                                mdi-pound-box
                            </v-icon>
                        </a>
                    </v-btn>
                </v-card-actions>
            </v-card>
        </v-flex>
    </v-layout>

双方向データバインディングでanimesという変数に値が入っていない場合は、結果部分は何も表示されないようにする

search.js
        /**
         * 年 + クールから対象のアニメリストを取得する関数
         */
        getAnime: function() {
            this.getYear();
            if (this.year && this.season) {
                // API: ShangriLa Anime API V1
                let api_url = "https://api.moemoe.tokyo/anime/v1/master/"
                this.animes = []
                axios.get(api_url + this.year + '/' + this.season, {
                }).then(response => {
                    for (let i = 0; i < Object.keys(response.data).length; i++) {
                        this.animes.push(response.data[i])
                    }
                })
            }
        }

コンボボックス側で指定されている関数
選択するたびに走るけど、年とクールが選択されていない限りは情報取得しないようにする

外部APIからjsonでデータ取得するためにはaxiosを使用する

アニメ情報取得には以下のAPIを使用しています

GET /anime/v1/master/:year/:n
:yearで指定されたYYYY年アニメの:nで指定されたクールの情報をすべて返します。

※参考
放映中のアニメ作品の情報を提供するAnime RESTful API サーバー作りました
axios を利用した API の使用

Vuetifyコンポーネントについて

Vuetify Component API Overview

公式のドキュメントに各コンポーネントの例とソースが記載されている
すごくわかりやすい

アイコンについて

Icon Component
Material Design Icons

Material Design Iconsのアイコンの利用をサポートしています。アイコン名にmdi-プレフィックスを付与するだけで使用できます。あなたのプロジェクトにMaterial Design Iconsを導入しておく必要があるので注意して下さい。

search.html
    <v-icon>
        mdi-twitter
    </v-icon>

これでTwitterアイコンなどが使用できる

デプロイ

サーバーレス+SPAなので、Github Pagesで簡単に公開したい
そのためビルド先のフォルダをdistからdocsに変更する

プロジェクトフォルダ直下に以下のファイルを作成する

vue.config.js
module.exports = {
    publicPath: "./",
    assetsDir: "",
    outputDir: "docs"
}

ビルドする

$ npm run build

ビルド完了後にgitに上げてGithub Pagesの設定をしてあげれば出来上がり

完成品

アニメ検索くん

ソースはこちら

とりあえずお手軽に作れました

最後に

こちらのAPIを使用させていただきました!素晴らしいAPIに感謝です!
https://github.com/Project-ShangriLa/sora-playframework-scala

Vueについて少ししか勉強してないのでもっと最適化できる部分あるかもって感じです
よろしければコメントなどでご指摘いただければと思います

4
3
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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?