寝て起きて寝て

プログラミングが出来ない情報系のブログ

VueJS入門メモ

どうやったらVueを使えるのか

<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
var app = new Vue({
    //options
  el:'#app'//←このid部分に囲まれている部分はVueを適用できる
})

一応これでもう使える。 ・・・が下記の部分に少し補足を加える。

<!--バージョン指定-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

<!--本番指定-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>

基礎知識

データバインディングとは

データと描画を同期する仕組みのこと。
応用するとinputタグの入力されたものを即時検索結果などに反映できたりする

Mustache構文

VueのプロパティをHTMLで使用したい場合Mustache構文を利用してテキストを展開する

<div id="app">
    {{message}
</div>
const app    = new Vue({
    el:'#app',
    data:{
        message:'Hello Vue!'
    }
})

テキストエリアではMustache構文を使用できないので下記のようにv-modelを使う

ちなみにVueインスタンス生成時には存在していなく、あとから動的に生成されたDOMに、
あとからマウントしたい場合は下記のように使う

const app    = new Vue({
    data:{
        message:'Hello Vue!'
    }
})
app.$mount('#app')

汎用的なディレクティブ

ディレクティブとは

ディレクティブは v- から始まる特別な属性。
ディレクティブ属性値は、単一の JavaScript 式を期待する。

例)
v-bind
v-if
など

v-bind

属性にはMustache構文を使用できない為v-bindを使って表記する

<div id="app">
    <input style="text" v-bind:value="message">
</div>
const app    = new Vue({
    el:'#app',
    data:{
        message:'Hello Vue!'
    }
})
<!--省略形-->
<input style="text" :value="message">

属性を動的に変化させたい場合は[]を使う
今回はhref属性を動的に変化できるようにしている

v-if

条件分岐条件式によって要素の挿入や削除を行う。
要素の挿入と削除を行うので、頻繁に切り替える場合はv-showを使うべきで
条件が実行時に変更することがほとんどない場合は、v-if を使用する。

<div id="app">
    <p v-if=isShow>
    {{message}}
    </p>
</div>
const app    = new Vue({
    el:'#app',
    data:{
        message:'Hello Vue!',
        isShow:false
    }
})

v-show

画面描画の表示・非表示を行う。
高い初期描画コストを持っているので頻繁に切り替えない場合はv-ifを使用する

<div id="app">
    <p v-show=isShow>
    {{message}}
    </p>
</div>

v-for

配列やObjectに基づいて、アイテムのリストを描画することができる

このディレクティブを使用する場合はkey属性を設定したほうがいい
理由は後述の問題点に記載

<div id="app">
    <ul>
        <li v-for="color in colors">{{color}}</li>
    </ul>
</div>
const app    = new Vue({
    el:'#app',
    data:{
        colors:["Red","Blue","Yellow"]
    }
})

出力結果

・Red
・Blue
・Yellow

・オブジェクトのキーを取り出す

<div id="app">
    <ul>
        <li v-for="(data,key) in personaldata">{{key}}:{{data}}</li>
    </ul>
</div>
const app    = new Vue({
    el:'#app',
    data:{
        personaldata:{
            Name:"Yamada",
            Age:18,
            Prefecture:"Tokyo"
        }
    }
})

出力結果

・Name:Yamada
・Age:18
・Prefecture:Tokyo

v-forの問題点

v-forには`要素の移動を最小限に抑えるアルゴリズムを使用し可能な限り同じタイプの要素を再利用するという性質があるため、要素を削除した場合の挙動がおかしくなる

どういうことかというと下記のようなプログラムでテキストに文字を入れた状態で
要素を削除すると削除前に入力した文字列がずれる。

f:id:krs1:20200528155553p:plain

これが

f:id:krs1:20200528155626p:plain

こうなる(本来であればテキストボックスには「青」「黄」の順に入力されていて欲しい

これは、削除前と削除後にレンダリングする際の差を考えて最適化して処理した
結果

今回の差としては要素が減るので、div,p,inputタグの減少とpタグ内の
文字列の変化なので、プログラム内で設定した文字列意外には干渉していない為こうなる

解決方法

一意のkeyを設定して削除する

<div v-for="color in colors" :key="color">

注意点

keyに下記のようにindexを指定している場合があるが、増減の可能性があり、
変化してしまう場合があるため非推奨

<div v-for="(color,index) in colors" :key="index">

v-on

要素にイベントリスナをセットする。

<div id="app">
    <button v-on:click="clickHandler">{{message}}</button>
</div>
const app    = new Vue({
    el:'#app',
    data:{
        message:"Click"
    },
    methods:{
        clickHandler:function(){
            this.message="Clicked"
        }
    }
})

v-bind同様に省略形でも記載することができる。

<div id="app">
    <button @click="clickHandler">{{message}}</button>
</div>

またイベント修飾子を指定できる
Vue.jsイベント修飾子一覧

インラインイベントハンドラ

簡単な処理であればインラインで処理が書ける

引数が複数あり、イベントオブジェクトを受け取りたい場合

$eventを引数に入れると受け取れる

システム修飾子

動作するキーを指定できる

v-model

input 要素 からの値に応じて能動的に変数値を変化することができる。

<div id="app">
    <p>
        {{message}}
    </p>
    <input type="text" v-model:value="message"/>
</div>
const app = new Vue({
    el:'#app',
    data:{
        message:"DefaultMessage"
    }
})

双方向データバインディング時は属性は無視される

下記コードはvalue="test"と入力しても、双方向データバインディングしているため反映されていない

デモ

上の基礎機能を応用して簡易掲示板機能を実装した デモ

@submit.prevent

これだけ補足
formによる送信機能を停止させるメソッド ページ遷移させないようにしている

TODOリストに関してはClassスタイルのバインディングを利用して実装している デモ2

クラスとスタイルのバインディングについては公式リファレンスを見たほうが良さそう