Vue.jsで何かつくる。
今回のProtooutstudioの課題で、GitHub上に公開されているネタからVue.jsで何かを作るというものでした。
そこで、せっかく来週オープンするカフェに関わるものを作ろうと考えました。
完成品がこちら。
あんまり上手くいかなかったけど、カフェの材料発注ウェブアプリをvue.jsで自作。#protoout pic.twitter.com/cP6XwDCtvh
— 北城雅照@足立慶友整形外科 (@kutuyanomusuko) December 16, 2020
見た目の修正はまだまだ必要ですが、必要な昨日はとりあえず実装できたと思います。
GitHubを検索し、cloneする。
いろいろと検索し、使えそうなものを発見したので、今回はこちらを使います。
動作のサンプルはこちらです。
右上のグリーンのCodeからURLを取得し、下記のコマンドを入力します。
$ git clone https://github.com/jamesgeorge007/Vue-ToDo.git
その後、使用するディレクトリーに移動し、
$ cd Vue-ToDo
必要なパッケージをインストールします。
$ npm install
試しに、下記のコマンドを入力して、ローカルサーバーで動かします。
$ npm run serve
下記のような表記が出ればOK。
LocalのURLをクリックすると、サンプルと同様なブラウザが立ち上がります。
サンプルコードを加工し、オリジナルにする。
vomponentsの中の、Stats.vueとToDo.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>
<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>
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から見ることができます。ご興味のある方はぜひ。
今後の課題
できれば、発注のボタンを押した時にwebhookなどを飛ばせる設定にしたかったのですが、うまく行かなかったので、今後修正したいと思います。
その他の記事
近すぎると小池都知事が『密です。』と連呼するデバイスを作ったら腹筋が崩壊したので、皆さんにも試して欲しい。
誰が使うかわからないけど、膝のレントゲン写真を送ったら、その膝がどの程度痛んでいるのか教えてくれるラインbotを作ってみた。