Vue.js + GraphQL(Graphcool) +vue-apolloでおこづかい帳を作る(1)

moneyforwardは使っている。家計簿アプリだから過去のことはよく分かるんだけど、これからいくら貯めたい!みたいな計画には使いにくかった。 なので、今まではGoogleDriveの表計算使って記録してたのだけれど、微妙に使いにくかったり、グラフがイケてなかったり…

ということで勉強がてら、自分専用おこづかい帳を作っていきたい。 ミニマムな要件としては、

・月の手取りから貯金するべき額(=お小遣いにしてもいい額)を出してくれる ・クライアント側からデータを入力できる ・任意の単位でいくら貯金したか出してくれる ・目標に対して貯蓄額がいくら過不足してるか計算してくれる ・グラフを描画してくれる

ということで頑張っていきたい。

Vue.js

Vue.jsとはMVVMパターンのフロントエンドフレームワーク。 。学習コストが低いのでおすすめ。

GraphQL/Graphcool

GraphQLはFacebook主導で開発しているクエリ言語。 jsonぽくクエリが書けるので、mySQLが苦手な自分でもココロの障壁なく書ける。

graphQLを使うにはサーバを立てる必要があるが、やりたいのはそこではないので、graphQLのBaaSであるgraphcoolをつかう。

無料アカウントだとデータ容量250MB、月は100,000アクセスまでだが、個人のお小遣い帳レベルではなんの問題もない。

vue-apollo

apolloとは、graphQLをクライアントサイドで使いやすくするためのライブラリ。vue-apolloはvue.js用にそれを落とし込んだもの。 Graphcool公式のquickstartにも紹介されてる。

graphcoolにデータを入力してAPIでひけるようにする

Payrollテーブルを作ってデータを入力。 income = 給料額 bonus = 賞与額 year = 年月日 remark = 備考

Payrollテーブル

APIのエンドポイントを取得。こんなやつ。https://api.graph.cool/simple/v1/{project_id}

vue-cliで使ってプロジェクトをセットアップ

1)incomeプロジェクトをつくる

vue init webpack-simple income
cd income
npm install

2)とりあえず起動する

npm run dev

main.jsを書き換える

//各種モジュールを呼び出す
import Vue from 'vue' 
import VueMaterial from 'vue-material
import VueApollo from 'vue-apollo';// Apolloの設定
import ApolloClient, { createNetworkInterface } from 'apollo-client';// 起動するモジュール
import App from './App.vue'// プラグイン
Vue.use(VueMaterial)// connect to GraphQL project
const apolloClient = new ApolloClient({
  networkInterface: createNetworkInterface({
    uri: ',
    transportBatching: true,
  }),
});Vue.use(VueApollo, {
  apolloClient,
});new Vue({
  el: '#app',
  render: h => h(App)
})

テーブルモジュールを作る。

#IncomeTable.vue(呼び出されるvueファイル)<script>import gql from 'graphql-tag'; //gqlモジュールを読み込む// graphQL Query
// とりあえずPayroleの全てデータを取得
const incomeQuery = gql `
{
  allPayrolls(orderBy:year_ASC) {
    id
    year
    income
    bonus
    remark
  }
}
`;export default {
    name: 'IncomeTable’, //モジュール名
    data() {
        return {
            allPayrolls: [], //レスポンスを入れるプロパティの初期化
            sum: {
                income: "",
                bonus: "",
            }
        }
    },
    filters: { 
/*略*/
    },
    computed: {
        sumByIncome: function() {
            return this.allPayrolls.reduce(function(a, b) {
                return {
                    income: a.income + b.income,
                    bonus: a.bonus + b.bonus
                }
            });
        }
    },
    // Apollo Settings
    apollo: {
        allPayrolls: { //vueのプロパティと同じ名前
            query: incomeQuery, //queryを結びつける
        },
    },
}
</script>

HTMLを書く

vue-materialを使っているので辺に見えますが、テーブルを生成してるだけです。

##IncomeTable.vue<template>
<md-table class="incomeTable">
    <md-table-header>
        <md-table-row>
            <md-table-head>年月</md-table-head>
            <md-table-head md-numeric>手取り額</md-table-head>
            <md-table-head md-numeric>賞与</md-table-head>
            <md-table-head md-numeric>合計</md-table-head>
            <md-table-head>備考</md-table-head>
        </md-table-row>
    </md-table-header><md-table-body class="incomeTable__body">
        <md-table-row v-for="(row, index) in allPayrolls" :key="row.id" class="incomeTable__row">
            <md-table-cell>{{row.year}}</md-table-cell>
            <md-table-cell md-numeric>{{row.income}}</md-table-cell>
            <md-table-cell md-numeric>{{row.bonus}}</md-table-cell>
            <md-table-cell md-numeric>{{(row.income + row.bonus) | currency}}</md-table-cell>
            <md-table-cell>{{row.remark}}</md-table-cell>
        </md-table-row></md-table-body>
</md-table>
</template>

app.vue

<template>
  <div id="app">
    <md-toolbar>
      <h1 class="md-title">{{title}}</h1>
    </md-toolbar>
    <income-table></income-table>
  </div>
</template><script>
import IncomeTable from './components/IncomeTable.vue'export default {
  name: 'app’,
  //コンポーネントの呼び出し(名前に注意)
  components: {
    'income-table’: IncomeTable,
  },
  data () {
    return {
      title: 'Pocket Money Book - GraphQL,Vue.js'
    }
  },
}
</script>

graphcoolからデータをひっぱってきて表示する所までが完成👏

ここまでは特に難しいことがなく。 データの追加には、を使う必要がある。次はこれかな。

Subjective Design

Web Design / Web Development / Service Design / Design Thinking / UX

Takahiro Hayashi

Written by

Service Designer 浅く広く手を出していく感じで。

Subjective Design

Web Design / Web Development / Service Design / Design Thinking / UX