Vue.js + Nuxt.js + Vuetify + PWA + Firebaseで家計簿アプリを作ってみた

なぜ作ろうと思ったか

Nuxt.jsの便利さ、手軽さを知って、一度アプリを作ってみたいと思っていた

もともとVue.jsに興味を持ち始めて、いろいろ勉強していました。あんまりVuexとか理解していない内にNuxt.jsに出会い、Vuex, Vue Routerがもともと組み込まれており、ディレクトリ構造に従って記述していけばアプリが開発できる手軽さに感動しました。

僕自身、Webアプリに興味を持ち始めて日が浅いので、今後のためにも何か成果物を作りたいと思ってました。Todoアプリとかチュートリアルで作るようなものを量産する毎日で、何か実践に役立つアプリを作ろうとアイデアを探してました。

結婚して約半年、奥さんから家計管理を楽にしたいと言われていた

そんな中、奥さんから家計管理について「なんか知りたい情報をパッと見れるようにしてくれない?」と相談されました。

結婚後、僕が使っていたメインの口座(給与振込される)を生活用口座にしたことで、我が家の家計管理が少し複雑になっていたようです。

  • 個人型確定拠出年金の引き落とし口座になっており、結婚前に拠出年金用資金としてまとまった金額を入金していた
  • 僕の会社は半年に一回、6ヶ月定期分の交通費が支給されるが、pitapaを使っているため交通費の引き落としは毎月となっていた

上記理由により、実質残っている残高が把握できない状態になっており、経理をしている奥さんはExcelでコツコツ複雑な計算をして家計簿をつけていました。

それならと、収入、支出を入力するだけで、知りたい情報を表示してくれるできるだけシンプル操作を意識したアプリを作ろうと決めました。

どんなアプリなのか

前述のアプリを作った経緯にもある通り、我が家のニーズだけに絞ってアプリを作成したため、我が家専用のアプリとなってます。

だったら、なぜこの記事を書くのかというと、私自身初めて使う技術ばかりで流行りのサーバーレス構成となっているので、使用技術、アプリ構成など同じように個人開発始めようとされてる方の参考になれば嬉しいと思ったからです。

アプリとしては単純な家計簿アプリで以下のような機能があります。

  • 支出、収入項目の入力
    • 日付、項目、金額を入力するだけです
  • カレンダーベースで表示月を選択
  • 各月ごとの収入合計、支出合計、損益、収入・支出項目一覧を表示
  • 各月ごとにメモの入力が可能
  • 口座残高の表示
  • 実質の口座残高の表示(確保しておくべき拠出年金と交通費を考慮した金額)

使用技術

  • Vue.js
  • Nuxt.js
  • Vuetify
  • PWA
  • Cloud Firestore
  • Firebase Authentication
  • Firebase Hosting

前述の経緯によりNuxt.jsで開発。UIフレームワークはNuxtと相性の良いVuetifyを採用しました。

今回はモバイル向けWebアプリなのでPWA対応としました。

サーバー環境はFirebase任せです。ホスティング、認証、データベースまとめて管理できるので実装はとても楽できました。

実装する上で手こずった箇所

金額入力時に自動で3桁ごとにカンマが付くようにした**

Oct-25-2018 20-33-28

入力した金額が分かりづらいと経理をやってる奥さんから要望があったので実装しました。

テキストフィールドで金額の入力時に自動的に3桁ごとにカンマを付けてくれる実装はあまり参考なのがなかったので苦労しましたが、以下のコードで実装できました。スマホで数字だけ入力しやすいようにtype="tel"としています。

あまり慣れていない身としてはこういう動きは完成したとき少し感動します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<template>
<v-text-field v-model="inputAmount" @blur="setBlur()" @keyup="setKeyup()" @keydown="setKeydown()" @keypress="setKeypress()" label="金額" prefix="¥" type="tel" required></v-text-field>
</template>

<script>
export default {
data () {
return {
isIME: false
}
},
methods: {
addFigure (value) {
let originValue = value
value = this.removeFigure(value)
value = parseInt(value, 10)
if (isNaN(value)) return originValue
return value.toString().replace(/(\d)(?=(\d{3})+$)/g, '$1,')
},
removeFigure (value) {
if (value.length === 0) return ''
let num = Number(value.toString().replace(/,/g, ''))
if (isNaN(num)) return value
return num
},
setKeydown () {
this.isIME = true
},
setKeypress () {
this.isIME = false
},
setKeyup () {
if (this.isIME === false) this.inputAmount = this.addFigure(this.inputAmount)
},
setBlur () {
this.inputAmount = this.addFigure(this.inputAmount)
}
}
}
</script>

Nuxt.jsでのFirebaseの連携

何せどちらも初めて使うので、どうやって連携させればいいか悩みました。

Nuxt.jsとfirestoreを組み合わせて簡単なサイトを作った話 | MOJIの本棚

上記のサイトを参考にFirestore, Authentication, Hostingを使うには以下の実装でできました。

firebaseのプロジェクト設定の読み込み

設定内容はFirebaseコンソール画面の「アプリにFirebaseを追加」から見れる内容です。

image-20181025210141842

上記から見れる設定内容を以下のように記載します。

今回はFirestore, Authenticationに必要な設定のみ記載しています。

1
2
3
4
5
6
7
// ./util/firebaseConfig.js
export default {
apiKey: '',
authDomain: '',
databaseURL: '',
projectId: ''
}

Nuxt.jsのプラグインファイルを作成

Nuxt.jsでfirebaseを扱うためにプラグインディレクトリにファイルを作成します。

ここでもFirestore, Authenticationに必要な設定のみ記載しているので、必要に応じて追加します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// ./plugins/firebase.js
import firebase from 'firebase'
import config from './../util/firebaseConfig'
import 'firebase/auth'
import 'firebase/firestore'

if (!firebase.apps.length) {
firebase.initializeApp(config)
}

const settings = { timestampsInSnapshots: true }

export const auth = firebase.auth()
export const DB = firebase.firestore()
DB.settings(settings)

export default firebase

使用したい箇所でimport

後はAuthentication, Firestoreを利用したvueファイル、jsファイルでimportするだけです。

1
import { auth, DB } from '~/plugins/firebase'

Hosting設定

Hostingへデプロイするためには、以下のfirebase cli用設定ファイルをプロジェクトディレクトリ内に作成します。

1
2
3
4
5
6
7
8
9
10
11
// ./firebase.json
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}

上記設定ファイルを作成しておくことで、firebase cliでコマンド一発でデプロイできます。

具体的には、Nuxt.jsで静的ファイルを生成

1
$ npm run generate

Firebase Hostingへデプロイ

1
$ firebase deploy
共有