9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue.jsでBMIを計算するアプリを作ってみた

9
Last updated at Posted at 2019-02-01

はじめに

文系出身エンジニアです。1年目です。

とある経緯でVue.jsを勉強する機会があったので、その際に作った、「身長と体重を入力すると、BMIを計算してくれる」というシンプルなアプリを作ったので、その記録を残します。

Vue.jsはおろか、Javascriptすらあやうい新人エンジニアなので、間違っているところ、改良すべきところがあったら、優しめに遠慮なくご指摘いただきたく存じます。

環境

  • MacOS v
  • Node.js v
  • npm V

基本のプロジェクトをインストール

基本となるプロジェクトは以下のチュートリアルを実行してゲットしました。

vue-cliで始めるVue.jsチュートリアル (1)

バージョンの関係か、この記事でsrc/components/Hello.vueと記載されているものは、実際はHelloWorld.vueとなりますが、使わないので気にしないでください。

完成イメージ

ezgif-2-8ce12c2cf323.gif

ポイントは、以下の3つです。

  • 身長と体重のinputが、リアルタイムで上に反映されていること
  • Figure outボタンを押すと、メッセージと共にBMIが表示されること
  • デモで入力されている身長と体重は私のものではないこと

コンポーネント作成

コンポーネントファイルの作成

コンポーネントファイルは、src/components内に、.vueという拡張子を付けて作成します。
以下は一例です。

$ touch {作成したプロジェクトのディレクトリ}/src/components/BmiFigureout.vue

そもそもコンポーネントとはなんぞやという方には、以下の記事がおすすめです。
Vue.jsコンポーネント入門

このファイルは長いので、解説は以下の3つに分けます。

  • 見た目(html)
  • 処理(javascript)
  • 装飾(css)

見た目を書く

まずは、<template>タグ内に、htmlで見た目の部分を書いていきます。

src/components/BmiFigureout.vue

<template>
    <div>
        <form id="input">
            <p>Your hight : {{ hight }} cm</p>
            <p>Your weihgt : {{ weight }} kg</p>
            <p>Input your hight here! -> <input type="text" v-model="hight"></p>
            <p>Input your weight here! -> <input type="text" v-model="weight"></p>
            <p><button class="figureout_btn" @click="emitFigureOut">Figure Out</button></p>
        </form>
    </div>
</template>

ここでは、身長と体重のinputと、入力した値をリアルタイムで表示する部分、BMIを算出するためのボタンを表しています。

入力した値をリアルタイムで反映

{{ hight }}{{ weight }}にそれぞれ入力した値が反映されます。

身長と体重のinput

反映する動きは、v-on:input="updateWeight($event.target.value)に書かれていて、具体的な処理は<script>タグ内のupdateWeightというメソッドに書かれています。

BMIを算出するためのボタン

<button>タグ内に書かれています。
ここで注目する箇所は、@click="emitFigureOut"です。
このボタンをクリックすると、emitFigureOutというメソッドが動きます。処理内容については次の項目で説明します。

追記

v-model="height":value="height" v-on:input="height =($event.target.value")の省略形だそうです。
教えてくださった@akicho8さん、ありがとうございます!

処理を書く

<script>タグ内に、Javascriptで処理の部分を書いていきます。

src/components/BmiFigureout.vue
<script>
export default {
    name: 'bmi',
    data () {
        return {
            hight : "",
            weight : ""
        }
    },
    methods: {
        updateHight: function(value){
            this.hight = value
        },
        updateWeight: function(value){
            this.weight = value
        },
        emitFigureOut () {
            var weightKg = this.weight
            var hightM = this.hight/100
            var bmiValue = weightKg / (hightM * hightM)
            this.$emit('figure-out', bmiValue)
        }
    }
}
</script>
dataについて

ここが無いとだめってことはわかりました。
どこかに値を返してそうなんですが、どこに返っているのかわかりません(小声)

updateWeightについて

入力された値をリアルタイムで表示するメソッドです。
詳しいことはわかりません。調査中です。
updateHightも同様です。

emitFigureOutについて

emitやイベント発行についてはこちらの記事で勉強しました。
Vue.jsコンポーネント入門 (4) $emitによるイベントの発行

身長と体重をそれぞれ変数に入れて、その変数を用いて計算したBMIの値を、bmiValueという変数に入れます。

イベントの発行
src/components/BmiFigureout.vueの下の方
this.$emit('figure-out', bmiValue)

this.$emit()でイベントの発行を表します。
第一引数には「イベント名」、第二引数にはイベントハンドラー(main.js)に渡したい値を入れます。

飾りを書く

<style>タグ内に、cssで飾り付けしていきます。
なくてもいいです。

src/components/BmiFigureout.vue

<style>
# input,#bmi {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 30px;
}
h1,h2 {
  font-weight: normal;
}
.figureout_btn{
    display: inline-block;
    padding: 0.5em 1em;
    text-decoration: none;
    font-weight: bold;
    font-size: 80%;
    background: #668ad8;
    color: #FFF;
    border-bottom: solid 4px #627295;
    border-radius: 3px;
}
.figureout_btn {
    -ms-transform: translateY(4px);
    -webkit-transform: translateY(4px);
    transform: translateY(4px);/*下に動く*/
    border-bottom: none;/*線を消す*/
}
</style>

イベントの処理を記述

main.jsに、イベントの処理を記述します。

src/main.js

import Vue from 'vue'
import Bmi from './components/BmiFigureOut.vue'

Vue.config.productionTip = false

const bmi = new Vue ({
  el: '#bmi',
  data : {
    msg: '🐽 Figure out your BMI 🐽',
    msgBmi: '',
    bmiValue: ''
  },
  components: { 
    Bmi
  },
  methods: {
    onFigureOut (bmi) {
      this.bmiValue = bmi
      this.msgBmi = 'Your BMI is....'
    }
  }
})
作成したコンポーネントを読み込む

二行目のimport文で、作成したコンポーネントを読み込みます。
読み込んだコンポーネントはBmiとして認識されます

返り値(?)

返す値をdataに記述します。
msgBmibmiValueは空になってるように見えますが、下のonFigureOutメソッドで代入されます。

コンポーネントの使用

読み込んだコンポーネントを以下のように記述すると、使用できるようになります。

src/main.jsの中盤
components: { 
    Bmi
  },
onFigureOutメソッド

イベントの発行で発行したイベントを処理する部分です。
onFigureOutは、ボタンをクリックすると起こるイベントで、このイベントには、引数(計算されたBMIの値)がありました。
その引数を、bmiValueに代入します。
また、msgBmiにメッセージも代入します。
このように記述することによって、ボタンが押下されると、返り値(data内)に値が代入されます。

ページにコンポーネントを表示させる

最後に、index.htmlに、コンポーネントを表示していきます。

index.html

<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>BMI</title>
  </head>
  <body>
    <div id='bmi'>
      <h1>{{ msg }}</h1>
      <bmi @figure-out='onFigureOut'></bmi>
      <h2>{{ msgBmi }} {{ bmiValue }}</h2>
    </div>
  </body>
</html>
コンポーネントの表示方法

以下のコードに注目してください。

index.htmlのタグ内
<bmi @figure-out='onFigureOut'></bmi>

main.jsで読み込んだコンポーネントBmi<bmi></bmi>とタグのように記述することによって、コンポーネントが表示されます。
@figure-out='onFigureOut'では、BmiFigureout.vueで発行されたイベントを、main.jsが読み込めるように形を変える役割をしています。

{{ msg }} {{ msgBmi }} {{ bmiValue }}

main.jsから返ってきたdataの中身がカッコ内{{ }}に入ります。

最後に

勉強しながら分かる範囲で書いてみました。

イメージとしては、
.vueファイル(コンポーネント)を作成
   ↓
emitでイベント発行(今回はボタン押下)
   ↓
main.jsでイベントの処理
   ↓
index.htmlでコンポーネント表示(+main.jsがイベントを処理できるように書き換え)

といった具合です。

間違っていることがあれば教えてください。(_ _)

9
4
4

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
9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?