はじめに
文系出身エンジニアです。1年目です。
とある経緯でVue.jsを勉強する機会があったので、その際に作った、「身長と体重を入力すると、BMIを計算してくれる」というシンプルなアプリを作ったので、その記録を残します。
Vue.jsはおろか、Javascriptすらあやうい新人エンジニアなので、間違っているところ、改良すべきところがあったら、優しめに遠慮なくご指摘いただきたく存じます。
環境
- MacOS v
- Node.js v
- npm V
基本のプロジェクトをインストール
基本となるプロジェクトは以下のチュートリアルを実行してゲットしました。
バージョンの関係か、この記事でsrc/components/Hello.vueと記載されているものは、実際はHelloWorld.vueとなりますが、使わないので気にしないでください。
完成イメージ
ポイントは、以下の3つです。
- 身長と体重のinputが、リアルタイムで上に反映されていること
-
Figure outボタンを押すと、メッセージと共にBMIが表示されること - デモで入力されている身長と体重は私のものではないこと
コンポーネント作成
コンポーネントファイルの作成
コンポーネントファイルは、src/components内に、.vueという拡張子を付けて作成します。
以下は一例です。
$ touch {作成したプロジェクトのディレクトリ}/src/components/BmiFigureout.vue
そもそもコンポーネントとはなんぞやという方には、以下の記事がおすすめです。
Vue.jsコンポーネント入門
このファイルは長いので、解説は以下の3つに分けます。
- 見た目(html)
- 処理(javascript)
- 装飾(css)
見た目を書く
まずは、<template>タグ内に、htmlで見た目の部分を書いていきます。
<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で処理の部分を書いていきます。
<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という変数に入れます。
イベントの発行
this.$emit('figure-out', bmiValue)
this.$emit()でイベントの発行を表します。
第一引数には「イベント名」、第二引数にはイベントハンドラー(main.js)に渡したい値を入れます。
飾りを書く
<style>タグ内に、cssで飾り付けしていきます。
なくてもいいです。
<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に、イベントの処理を記述します。
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に記述します。
msgBmiとbmiValueは空になってるように見えますが、下のonFigureOutメソッドで代入されます。
コンポーネントの使用
読み込んだコンポーネントを以下のように記述すると、使用できるようになります。
components: {
Bmi
},
onFigureOutメソッド
イベントの発行で発行したイベントを処理する部分です。
onFigureOutは、ボタンをクリックすると起こるイベントで、このイベントには、引数(計算されたBMIの値)がありました。
その引数を、bmiValueに代入します。
また、msgBmiにメッセージも代入します。
このように記述することによって、ボタンが押下されると、返り値(data内)に値が代入されます。
ページにコンポーネントを表示させる
最後に、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>
コンポーネントの表示方法
以下のコードに注目してください。
<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がイベントを処理できるように書き換え)
といった具合です。
間違っていることがあれば教えてください。(_ _)
