0
1

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 3 years have passed since last update.

Vue.jsでTodoistを模してTodoアプリを作ってみた①

Posted at

はじめに

少し前に、TodoistからTrelloへ乗り換えたのですが、Todoistが何となく恋しかったので、
Vue.js学習のアウトプットとしてTodoistのクローンアプリを作ろうと思いました!
作ってみると学ぶことだらけで、何かにまとめたいと思ったので記事を書くことにしました。

URL https://todoist-clone-c2bd0.web.app/

使用したツール

  • VueRouter
  • Vuex
  • Firebase

VueRouter

routerはこのような感じです。
今回作成したページは インボックス・今日・近日中・プロジェクト です。

router/index.js

import Vue from "vue";
import VueRouter from "vue-router";

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "inbox",
    component: () => import("../views/Inbox.vue"),
  },
  {
    path: "/today",
    name: "today",
    component: () => import("../views/Today.vue"),
  },
  {
    path: "/fewday",
    name: "fewday",
    component: () => import("../views/Fewday.vue"),
  },
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
});

export default router;

Vuex

firebaseに格納されているtaskのデータはこんな感じです。
titleがタスクの名前
dueDateが期日になっています。

{
id:"hogehoge",
data:{
  title:"string",
  dueDate:{
     seconds:101010101  //(timestamp)
    }
  }
}

storeはこんな感じです。 tasksしかないのですが学習のためと思ってモジュール化しました

store/index.js

import Vue from "vue";
import Vuex from "vuex";
import tasksModule from "./tasks";

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    tasksModule,
  },
});

tasks.js

import firebase from "firebase";

const state = {
  tasks: [],
};

const getters = {
// Viewで使うときには並び順は期日順にしたいので、ここで並び替えの処理を書きます
  tasks(state) {
    let tasks = state.tasks;

    tasks.sort((a, b) => {
      if (a.data.dueDate.seconds < b.data.dueDate.seconds) return -1;
      if (a.data.dueDate.seconds > b.data.dueDate.seconds) return 1;
    });
    return tasks;
  },
};

const mutations = {
  fetchTasks(state, data) {
    state.tasks.push(data);
  },
  doneTask(state, id) {
    state.tasks = state.tasks.filter((el) => {
      return el.id != id;
    });
  },
  addTask(state, newTask) {
    state.tasks.push(newTask);
  },
};

const actions = {
// firebaseから全てのタスクを取得する処理
  fetchTasks({ commit }) {
    firebase
      .firestore()
      .collection("tasks")
      .get()
      .then((response) => {
        response.forEach((doc) =>
          commit("fetchTasks", { id: doc.id, data: doc.data() })
        );
      });
  },
// タスクを完了とする処理です。 データから削除しています。 フラグなんかをもたせる方いいかもです。
  doneTask({ commit }, { id }) {
    firebase
      .firestore()
      .collection("tasks")
      .doc(id)
      .delete()
      .then(() => {
        commit("doneTask", id);
      });
  },
// タスクを追加する処理です。 firebaseにpostします
  addTask({ commit }, newTask) {
    firebase
      .firestore()
      .collection("tasks")
      .add(newTask)
      .then((doc) => {
        commit("addTask", { id: doc.id, data: newTask });
      });
  },
};

const tasksModule = {
  namespaced: true,
  state,
  getters,
  mutations,
  actions,
};

export default tasksModule;

View

雛形となるApp.vueはこんな感じです。

App.vue

サイドバーのナビで 表示するViewを制御しています。
一番初めにタスクを取得したいのでcreatedでfetchTasksを実行します。


<template>
  <div>
    <nav class="uk-navbar-container uk-margin" uk-navbar id="nav">
      <div class="uk-navbar-left">
        <div>
          <a
            class="uk-navbar-toggle"
            uk-navbar-toggle-icon
            href=""
            @click.prevent="toggleNav"
          ></a>
        </div>

        <ul class="uk-navbar-nav">
          <li>
            <a href="/">
              <span
                class="uk-icon uk-margin-small-right"
                uk-icon="icon: home"
              ></span>
            </a>
          </li>
        </ul>

        <div class="uk-navbar-item">
          <input
            class="uk-input uk-form-width-medium"
            type="text"
            placeholder="Search"
          />
        </div>
      </div>
    </nav>
    <div>
      <transition tag="div" name="slideX">
        <div class="uk-width-1-4@s side-nav" v-show="isNavShow">
          <ul class="uk-nav-default uk-nav-parent-icon" uk-nav>
            <li class="uk-active">
              <router-link to="/">インボックス</router-link>
            </li>
            <li class="uk-active">
              <router-link to="/today">今日</router-link>
            </li>
            <li class="uk-active">
              <router-link to="/fewday">近日中</router-link>
            </li>

            <li class="uk-nav-divider"></li>
          </ul>
        </div>
      </transition>

      <router-view id="container" />
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isNavShow: true,
    };
  },
  methods: {
    toggleNav() {
      this.isNavShow = !this.isNavShow;
    },
  },
  created() {
    this.$store.dispatch("tasksModule/fetchTasks");
  },
};
</script>
0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?