LoginSignup
1
1

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-12-16

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の弱点を克服し、最強化する方法を書くので試して欲しい。

1
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
1
1