LoginSignup
1

More than 1 year has passed since last update.

posted at

updated at

Organization

来週オープンする自分のカフェの発注web appを、GitHubからcloneしてVue.jsで作ってみた。

Vue.jsで何かつくる。

今回のProtooutstudioの課題で、GitHub上に公開されているネタからVue.jsで何かを作るというものでした。
そこで、せっかく来週オープンするカフェに関わるものを作ろうと考えました。
完成品がこちら。

見た目の修正はまだまだ必要ですが、必要な昨日はとりあえず実装できたと思います。

GitHubを検索し、cloneする。

いろいろと検索し、使えそうなものを発見したので、今回はこちらを使います。
動作のサンプルはこちらです。

右上のグリーンのCodeからURLを取得し、下記のコマンドを入力します。
スクリーンショット 2020-12-16 23.20.23.png

$ git clone https://github.com/jamesgeorge007/Vue-ToDo.git

その後、使用するディレクトリーに移動し、

$ cd Vue-ToDo

必要なパッケージをインストールします。

$ npm install

試しに、下記のコマンドを入力して、ローカルサーバーで動かします。

$ npm run serve

下記のような表記が出ればOK。
LocalのURLをクリックすると、サンプルと同様なブラウザが立ち上がります。
スクリーンショット 2020-12-16 23.37.05.png

サンプルコードを加工し、オリジナルにする。

vomponentsの中の、Stats.vueとToDo.vueを下記のように加工しました。

Stats.vue
<template>
  <div>
    <h1 class="display-3 font-weight-bold font-color-red">全削除</h1>
    <h2>項目を全消去したい時のみ押してください。</h2>
    <p>発注希望、及び、発注済みが全部で {{ countTasks }} 項目あります。</p>
    <v-btn x-large color="red" v-on:click="removeAllTasks">全削除</v-btn>
    <p>{{ msg }}</p>
  </div>
</template>

<script>
import { mapGetters, mapMutations, mapActions, mapState } from "vuex";

export default {
  name: "Stats",
  computed: {
    ...mapGetters(["countTasks"]),
    ...mapState(["msg"])
  },
  methods: {
    ...mapMutations(["REMOVE_ALL"]),
    ...mapActions(["removeAll", "updateStatus"]),
    async removeAllTasks() {
      await this.removeAll();
      this.updateStatus();
    }
  }
};
</script>

<style></style>

ToDo.vue
<template>
  <div>
    <div class="maemae">
     <h1 class="display-2 font-weight-black">Hawaiian Cafe Mae'emae'e</h1>
      <img src="./maemaeL.png">
    </div>
     <div>
      <Stats />
    </div>
    <div class="left">
      <v-container>
        <h1 class="display-2 font-weight-black">{{ title }}</h1>
        <v-form @submit.prevent="addTask">
          <v-text-field label="発注希望品" v-model="newTask"> </v-text-field>
        </v-form>
        <v-list
          v-for="(task, index) in tasks"
          v-bind:key="index"
          v-if="!task.done"
        >
          {{ task.text }}<v-btn dark
            v-on:click="doneTasks(index, true)"
          >発注</v-btn>
          <v-btn v-on:click="removeTasks(index)">削除</v-btn>
        </v-list>
      </v-container>
    </div>
    <div class="right">
      <v-container>
        <h1 class="display-2 font-weight-black">発注済み</h1>
        <v-list
          v-for="(task, index) in tasks"
          v-bind:key="index"
          v-if="task.done"
        >
          {{ task.text }}
          <v-btn
            dark
            v-on:click="doneTasks(index, false)"
          >発注リストに戻す</v-btn>
          <v-btn v-on:click="removeTasks(index)">削除</v-btn>
        </v-list>
      </v-container>
    </div>

  </div>
</template>

<script>
import { mapState, mapMutations, mapActions } from "vuex";
import Stats from "./Stats.vue";

export default {
  name: "ToDo",
  data() {
    return {
      newTask: ""
    };
  },
  computed: {
    ...mapState(["title", "tasks"])
  },
  components: {
    Stats
  },
  methods: {
    ...mapMutations(["ADD_TASK", "DONE_TASK"]),
    ...mapActions(["removeTask", "removeStatus"]),
    addTask: function() {
      if (!this.newTask) {
        alert("Kindly provide a task");
        return;
      }
      this.ADD_TASK(this.newTask);
      this.newTask = "";
      this.removeStatus();
    },
    removeTasks: function(task) {
      this.removeTask(task);
    },
    doneTasks: function(index, done) {
      this.DONE_TASK({
        index,
        done
      });
      this.removeStatus();
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.left {
  float: left;
  padding-left: 10vw;
}
.right {
  float: right;
  padding-right: 10vw;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: block;
  margin: 0 10px;
}
i:hover {
  cursor: pointer;
}
</style>
store.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    title: "発注希望",
    msg: "",
    tasks: [
      {
        text: "オーガニックコーヒー 5kg",
        done: false
      },
      {
        text: "ハワイアンコーヒー 10packs",
        done: false
      },
      {
        text: "ハワイアンフレーバーコーヒー 10packs",
        done: false
      },
      {
        text: "アップグレードコーヒー ココナッツ 3packs",
        done: false
      },
      {
        text: "アップグレードコーヒー ココア 3packs",
        done: false
      },
      {
        text: "アップグレードコーヒー ダークモカ 3packs",
        done: false
      }
    ]
  },

  getters: {
    countTasks: state => {
      return state.tasks.length;
    }
  },

  mutations: {
    ADD_TASK: (state, task) => {
      state.tasks.push({
        text: task,
        done: false
      });
    },
    REMOVE_TASK: (state, task) => {
      state.tasks.splice(task, 1);
      state.msg = "Successfully removed!";
    },
    REMOVE_ALL: state => {
      state.tasks = [];
    },
    REMOVE_STATUS: state => {
      state.msg = "";
    },
    UPDATE_STATUS: state => {
      state.msg = "項目を全て削除しました。";
    },
    DONE_TASK: (state, obj) => {
      state.tasks[obj.index].done = obj.done;
    }
  },

  actions: {
    removeTask: (context, task) => {
      context.commit("REMOVE_TASK", task);
    },
    removeAll({ commit }) {
      return new Promise(resolve => {
        setTimeout(() => {
          commit("REMOVE_ALL");
          resolve();
        }, 100);
      });
    },
    removeStatus: context => {
      context.commit("REMOVE_STATUS");
    },
    updateStatus: context => {
      context.commit("UPDATE_STATUS");
    }
  }
});

完成

$ npm run build

を行い、完成したdistファイルをnetlifyにデプロイしました。
下記のQRから見ることができます。ご興味のある方はぜひ。
QR_150831.png

今後の課題

できれば、発注のボタンを押した時にwebhookなどを飛ばせる設定にしたかったのですが、うまく行かなかったので、今後修正したいと思います。

その他の記事

近すぎると小池都知事が『密です。』と連呼するデバイスを作ったら腹筋が崩壊したので、皆さんにも試して欲しい。

誰が使うかわからないけど、膝のレントゲン写真を送ったら、その膝がどの程度痛んでいるのか教えてくれるラインbotを作ってみた。

猪木の名言で元気をくれるbotを作ったら、想定外の応答で笑いが止まらなくなったから、ぜひ試して欲しい。

twitterが使えないというIntegromatの弱点を克服し、最強化する方法を書くので試して欲しい。

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
What you can do with signing up
1