みんなの「作ってみた」

【個人開発】Webサービス:「人生でやりたい100のこと」の作成

2019/06/19

yoshi_yast
yoshi_yast
個人開発初学者です。個人の記録をOUTPUTしていきたいと思います。

【個人開発】Webサービス:「人生でやりたい100のこと」を作成しました(Vue.js + Python/Django)

はじめに(自己紹介)

  • IT業界にずっと身を置いているものの、企業向けのシステムを扱っているのものあり、WEBサービスを自分で最初から最後まで作成したことはありませんでした。(30代後半のアラフォーです)
  • Qiitaでこちら(「中年の危機」ど真ん中のオッサンがWEBサービス作ってみた)の投稿を拝見して、前々から思っていた「このままでよいのか」と「何番煎じでもよいし、ありふれたものでもよいので、なにかを作りたい(作りきってみたい)」がつながり、作成に取りかかることにしました。

何をつくろうと思ったか

  • 「人生でやりたいことリスト100」というのをgoogle検索すると、検索結果は色々でてきますが、皆さん自分のブログで書いています。ブログに書くのももちろんありだと思いますが、ブログを持っていないとか、もしくは、メンテナンスとか考慮して、自分で簡単に管理することができるとよいのではないか、と思いました。
  • そこで、人生でやりたい100のこと、というタイトルでWebサービスを作成しようと思いました。
※余談:仕事をしていると、ついつい「できること」(Can)で考えがちですし、そうすべきこともたくさんあります。ただ、人生という視点で考えれば、「やりたいこと」(Want)を常に頭に置いておきたいと思っています。
【参考本】人生の100のリスト(Amazon)

こだわったこと

唯一のこだわりは、SPA(Single Page Application)として開発すること。登録や変更などで画面遷移しているのはすごく煩わしいので、自分のやりたいこと(wants)を1画面にて簡単に追加・変更等の管理ができるようにしたい。

機能・できること

簡単に言ってしまうと、Todoリストの拡張版。ただ、チェックボックスがあるような、Todoリストではなく、下記のような機能をつける。

  • 100のことなので、数字つきのリスト
  • 簡単(ドラック&ドロップ)に上へ下へ移動
  • 達成日 / 達成時コメント が入力できる
  • 達成率がグラフなどで見える
  • 自分のリストのダウンロード
  • やりたいこと(want)単位で、公開/非公開設定ができる(見せたくない場合は非公開にする)
  • 他の人のWantsリストも参照できるので(公開のみ)、共感できるものは「いいね」ができる

使用技術

<フロントエンド>
・Vue.js / Vuex

<バックエンド>
・Python3.6 / Django2.0 / REST Framework
・MySQL

公開サイト

勉強のため、下記の2つで構築・公開

レンタルサーバー
フロントとバックを違う環境で構築し、APIを呼ぶ
 - フロント:レンタルサーバー(Vue.js)
 - バックエンド:Heroku(Python + Django REST Framework + MySQL)
  ※Herokuは一定時間アクセスがないとスリープになるので、少し待つ場合あり

AWS  ※ただしhttps非対応

実施した勉強

Vue.jsも、Django REST FrameworkによるAPI構築もはじめてやりましたので、勉強のために下記を実施。

  • Vue.js / APIの呼出しについて

    • Qiita APIを呼び出し、キーワードによるリアルタイム検索をやってみる → Heroku
  • Python Djangoについて

    • TodoリストでCRUDを学ぶ → Heroku
  • Django REST Framework / Vue.js関連の参考URL

    • 皆様のQiita投稿を参考にさせていただき、同じことをしてみる。

【参考URL】
Python Django チュートリアルまとめ
Django REST Frameworkを使って爆速でAPIを実装する
Django + Vue.js な開発環境を作ろう
Django REST framework with Vue.js
Django REST Frameworkでユーザ認証周りのAPIを作る
Django REST framework カスタマイズ方法 - チュートリアルの補足
サーバーサイドJavaエンジニアがVue.jsの基本を学習したときのメモ

実装のポイント

Vue.draggable:ドラッグアンドドロップで自分のWantsを移動させる

Vue.jsでドラッグ&ドロップするなら「Vue.Draggable」がおすすめらしい。

【インストール】 npm i -S vuedraggable

【参照URL】
https://github.com/SortableJS/Vue.Draggable
https://www.kabanoki.net/1712
https://qiita.com/kimuray/items/d728fa1635aeacad359f
http://sagatto.com/20171031_vuejs_sortable

wantslist.vue
<draggable v-model="wants" :element="'tbody'" :options="{handle:'.handle', animation:150, delay:150}" v-on:end="onEnd">

 // ドラック&ドロップ対象のテーブルを囲む

</draggable>

<script>
import draggable from 'vuedraggable'

export default {
  name: 'WantsIndex',
  components: {
    Chart,
    draggable
  },
  data () {
    //省略
  },
  computed: {
    //省略
  },
  created () {
    //省略
  },
  methods: {
    // Vue.Draggableの移動が終わったら処理を実施
    onEnd () {
      var num = 0
      // wantslistをループして、更新データを作成する
      for (var i = 0; i < this.wants.length; i++) {
        num += 1
        var addnum = {
          id: this.wants[i].id,
          displayOrder: num
        }
        this.upwants.push(addnum)
      }
      // 更新処理を実施
      axios.patch(`${process.env.API_ENDPOINT}wantsupdate/`, {
        upwants: this.upwants
      })
    },
  //省略
  }
}
</script>

Chart.js:未着手・実施中・達成のステータスを円グラフ化

vue-chartjsを使用すると、簡単にグラフが作成できる。

wantslist.vue
<template>
  <div class="container">
    <br>
    <div class="card-group">
   
   // 省略

      <!-- カード3: 100wantsのドーナツチャート -->
      <div class="card">
        <Chart :chart-data="datacollection" :height="200"></Chart>
      </div>
    </div>    
    <br>

    // 省略

  </div>
</template>

<script>
import Chart from './Chart.js'

export default {
  name: 'WantsIndex',
  components: {
    Chart,
    draggable
  },
  data () {
    //省略
  },
  computed: {
    //省略
  },
  created () {
    //省略
  },
  methods: {
    fetchData () {
         // 省略
    },
    // グラフデータの取得
    getChartdata () {
      this.datacollection = {
        labels: ['未着手', '実施中', '達成'],
        datasets: [
          {
            data: [this.getStatus('nostart'), this.getStatus('doing'), this.getStatus('done')],
            backgroundColor: ['lightgreen', 'lightblue', 'lightgray']
          }
        ]
      }
    },
  }
}
</script>

Vue-Gravatar:グローバルに認識されるアバター

アバターアイコンは、ユーザに登録してもらいDBにて保持する形ではなく、グローバルに認識されるアバターを登録してもらい、それを表示されるようにする(e-mailアドレスでの紐付け)

v-gravatar と指定して、emailアドレスをv-bindする。

【参照URL】
https://ja.gravatar.com
https://www.npmjs.com/package/vue-gravatar

wantslist.vue
<!-- カード1: ユーザの情報(e-mailアバター、ニックネーム、likes一覧、いいね数、twitterアイコンを表示) -->
  <div v-for="user in users" v-bind:key="user.id" class="card">
    <div class="card-body">
      <span><v-gravatar v-bind:email="user.email" :size="60" class="w-30 rounded" default-img="mm"/>
        <strong>{{ user.nickname }}</strong>
      </span>
      <br><br>
      <small><router-link to="/userlikelist"><button class="btn-sm btn-warning">Likes一覧</button></router-link></small>
      <small><button v-on:click="download()" class="btn-sm btn-success">List Download</button></small>
    </div>
  </div>

まとめ

  • 初学者としては、言語の基礎を学んだあとは、チュートリアルとして、TodoList・掲示板・Twitterのような投稿システムなどを作成してみる、という流れが多いと思いますが、その次のステップとして、それらの機能を拡張していくのが、とてもやりやすいのではないか、と作りながら思いました。

  • Django REST Framework API の便利さ、Vue.jsのおもしろさ・難しさ、などいろいろ感じることができました。

感想・その他

  • ログイン機能実装、DB連携、CRUDなどもはじめて実施しましたので、とても苦労しましたが、徐々に機能がついていき、できることが増えていくときなどとても充実感がありました。

  • 今回使用した、Django REST Framework API、Vue.jsなどはじめて触りました。当然、いろいろなところでつまりながらです。仕事以外の時間はすべてこれに費やした感じがします。(約3ヶ月弱くらい)

  • やっているときは、Qiitaをめちゃくちゃ参考にさせていただきました。結果をQiitaに投稿することが1つの大きな目標になり、その目標も達成することができました。(本投稿)