#Tl;DR
##あなた誰?
はじめまして。葉月ゆき(@peridot_snow08)、初投稿です。
フロント未満コーダー以上の存在でエンジニアをやりつつ都内でほそぼそしてます。
##何やったの?
前から興味があったVueで簡単などうぶつの森 カブ損益ツールを作りました!
きっとまだ不完全だと思われる部分もあるけど、公開はできた!
なのでやってきたことを振り返ろうと思います。
##振り返り
###各値の入力と結果の表示
始めにここを作ったので、数値入力と結果が親子関係になってないです。
見返すと、親子関係にしたほうがよかったかなぁって思います。
<template lang="pug">
div.bellInput
div.trade
.buyKabu.kabuPrice
label(for='buyBell') 買値
div.kabuPriceInput
input#buyBell(type='number', v-model.number='buyPrice' placeholder="100")
span ベル
.sellKabu.kabuPrice
label(for='sellBell') 売値
div.kabuPriceInput
input#sellBell(type='number', v-model.number='sellPrice' placeholder="100")
span ベル
.kabuNumber
label(for='kabuNumber') 購入数
.kabuPriceInput
input#kabuNumber(type='number', v-model.number='kabuNumber' placeholder="100")
span カブ
h2.result 購入結果
table
tr
td.first 購入合計
td
span.priceTxt {{buyTotal | numberGrouping}}
span ベル
tr
td.first 買取合計
td
span.priceTxt {{sellTotal | numberGrouping}}
span ベル
tr.borderNone
td.first カブ損益
td
span(:class="{active : kabuTotal < 0}").priceTxt {{kabuTotal | numberGrouping}}
span ベル
Tanukichi(:kabuTotal="kabuTotal")
StrageBtn(:buy="buyPrice" :sell="sellPrice" :total="kabuNumber")
</template>
<script>
import Tanukichi from './Tanukichi.vue'
import StrageBtn from './StrageBtn.vue'
export default {
name: 'BellInput',
components: {
Tanukichi,
StrageBtn
},
data(){
return {
buyPrice: '',
sellPrice: '',
kabuNumber:'',
}
},
mounted() {
if(localStorage.length > 0) {
this.buyPrice = localStorage.getItem('buy')
this.sellPrice = localStorage.getItem('sell')
this.kabuNumber = localStorage.getItem('total')
}
},
computed: {
buyTotal(){
return this.buyPrice * this.kabuNumber
},
sellTotal(){
return this.sellPrice * this.kabuNumber
},
kabuTotal(){
return this.sellTotal - this.buyTotal
},
},
filters: {
numberGrouping(price){
return price = price.toLocaleString()
}
}
}
</script>
各値はv-model、結果computedで計算し、Filterを使って3桁区切りをしています。
computedで桁区切りを行うと型変換が起こってしまうため、propsで渡すと文字列として渡してしまいます。
これだと後で支障きたすため、Filterを使いマスタッシュの中で桁区切りを行ってます。
コードの見たわしが若干悪くなるけど、地味に便利だったので採用。
各計算結果と入力値は使うので、propsで子Componentに渡してあげてます。
###たぬきちのアドバイス
各値を入力すると、たぬきちがアドバイスをくれます。
たぬきち曰くプラマイ0は運命らしいです。
<template lang="pug">
div.tanukichi
p.name たぬきち
vue-typer(
:text="tanukichiTalk"
:repeat='0'
)
</template>
<script>
/* eslint no-irregular-whitespace: ["error", {"skipTemplates": true}] */
import { VueTyper } from 'vue-typer'
export default {
name: 'Tanukichi',
components: {
VueTyper
},
props: {
kabuTotal: {
type: Number
}
},
data() {
return {
tanukichiTalk:`数値を入力をしてだなも。\n3つの数字をいれると、自動的に金額がでるだなも!`
}
},
watch: {
kabuTotal(newTotal){
if(newTotal > 0){
this.tanukichiTalk = `今 カブを売ると儲けでるだなも!\n売り値が上がるともっと儲けることができるから、もう少し待ってみるだなも。`
} else if( newTotal < 0) {
this.tanukichiTalk = `あわわわ! 損がでちゃただなも!\n明日になったらカブ価が回復するかも…\n今は売らずに待つのがよいだなも!`
} else {
this.tanukichiTalk = `プラスマイナス0だなも。\n損をしなくて済むから今売るといいだなも!`
}
}
},
}
</script>
パッ切替わると味気がないので、ちゃんと会話ウィンドウっぽく喋ってくれるように、タイピングエフェクトにはVueTyperを使いました。
株価の損益の結果の値を親からもらい、たぬきちのセリフを変えてます。
セリフの切り替えをmethodsでやろうとしましたが、処理が重くなりそうなので、watchで処理。
###ヘルプのモーダル
ヘルプの部分を押すと、ヘルプのモーダルが開きます。
Componentを別にし、App.vue経由でModalを表示させるかを制御してます。
<template lang="pug">
transition(name="modal")
div
div.modalOverlay
span.modalCloseBtn
div.modalContents
div.useHead 使い方
ul.howToUse
li 買値・売値・購入数の3つを入力すると、購入結果に自動で計算結果が出力されます。購入結果がマイナスになると、損益が赤く表示されます。
li 【結果を保存する】のボタンを押すと、ブラウザに買値・売値・購入数の入力値が保存され、次回アクセス時に自動で挿入されます。
li 【保存データを破棄】を押すとブラウザに保存されたデータは破棄されます。入力結果はそのまま残りますので、日曜日のタイミングなどに使うといいかもです。
p 開発の要望などは<a href="https://twitter.com/peridot_snow08" target="_blank">葉月ゆき</a>のTwitterにてお寄せください。
button(@click="modalClose") ヘルプを閉じる
</template>
<script>
export default {
name:'Modal',
methods: {
modalClose(){
this.$emit('modalClose')
}
},
}
</script>
<template lang="pug">
div#app
Header(@modalOpen = 'toggleModalFlag')
BellInput
Modal(v-if="modalFlag" @modalClose = 'toggleModalFlag')
</template>
<script>
import Header from './components/Header.vue'
import BellInput from './components/BellInput.vue'
import Modal from './components/Modal.vue'
export default {
name: 'App',
components: {
Header,
BellInput,
Modal
},
data(){
return {
modalFlag: false
}
},
methods: {
toggleModalFlag(){
this.modalFlag = !this.modalFlag
}
},
}
</script>
子から親へは基本イベントしか渡せないというので、Headerでクリックイベントを発火させて、App.jsの切り替えメソッドに伝搬させ、それをpropで真偽値を渡すということをしてます。
クローズのときもApp.jsの切り替えメソッドまでは同じ。
こんなことをやりつつ、損益ツールは動かして作りました。
ただ…モーダルを表示時にactive-enterが入らないのでトランジションが動きません…。
##完成した感想
基礎を叩き込むまで随分時間はかかってしまいましたが、理解をするとこんなにも便利フレームワークがあるのか!一気に世界が開けた気がしました。特にデータバインディングの利便性はとってもすごい。
ツール自体まだ甘いところはありますが、インプットだけではと思い、こんなツールを作った次第です。誰かの役に経てばいいな。
Vue自体に特に大きな制約もないため、これからどんどんいろんなものを作って行きたいと思います。
##最後に
お友達がいないのでお友達募集中です。
Twitterやってるので、お友達になってください…