와우! 두부의 숲 새끼 손익 도구를 Vue로 만들었어!

Tl;DR


  • Vue Cli를 사용하여 두꺼운 숲 새끼 손익 도구를 만들었습니다
  • 완성된 것은 여기야.
  • GitHub는 이것이야.

  • 너 누구?



    만나서 반갑습니다. 하즈키 유키 (@peridot_snow08) , 첫 투고입니다.
    프론트 미만 코더 이상의 존재로 엔지니어를 하면서 도내에서 흩어져 있습니다.

    무슨 일이야?



    이전부터 관심이 있던 Vue로 간단한 어둠의 숲 새끼 손익 도구를 만들었습니다!


    분명 아직 불완전하다고 생각되는 부분도 있지만, 공개는 할 수 있었다!
    그래서 온 것을 되돌아 보려고 생각합니다.

    되돌아가다



    각 값 입력 및 결과 표시



    처음에 여기를 만들었으므로, 수치 입력과 결과가 부모와 자식 관계가 되어 있지 않습니다.
    보답하면, 부모와 자식 관계로 하는 것이 좋았을까라고 생각합니다.

    BellInput.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은 운명인 것 같습니다.

    BellInput.vue
    <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을 표시할지 여부를 제어합니다.

    Header.vue
    <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>
    

    App.js
    <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 자체에 특히 큰 제약도 없기 ​​때문에, 앞으로 점점 다양한 것을 만들어 가고 싶습니다.

    마지막으로



    친구가 없기 때문에 친구 모집 중입니다.
    트위터 하고 있기 때문에, 친구가 되어 주세요…

    좋은 웹페이지 즐겨찾기