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

Takahiro Hayashi
Subjective Design
Published in
9 min readMar 24, 2017

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: '
https://api.graph.cool/simple/v1/hogehoge',
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からデータをひっぱってきて表示する所までが完成👏

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

--

--

Takahiro Hayashi
Subjective Design

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