ryota21silvaの技術ブログ

Funna(ふんな)の技術ブログ

これまで学んだ技術の備忘録。未来の自分が救われることを信じて

Vueのデータバインディングとか基礎的なのをまとめてみた(v-bind, v-on, v-for, v-model, componentとか)

Vueのデータバインディング


追記(6/15)

  • バインディングとは、データとUIを結びつけること
  • 双方向とは、データを更新⇄UIを更新
  • dataで、データを保持させる
    name(プロパティ)とvalueのセット。
  • {{ }}にはjsの式も書ける

  • new VueはVue.jsの心臓部分みたいなもの。
  • Vueインスタンスelで、Vueがどの部分のテンプレートを扱うか判断してくれる(VueインスタンスをDOM要素(HTMLとか)に紐付ける)
    el: '#app'<div id='app'>に紐付く。
  • マスタッシュ構文{{ 〇〇 }}を使うことで、テンプレート内のデータオブジェクトにアクセスできる。
    →{{ }}内にはJavascriptの記述ができる。{{ name.toUpperCase }}とか。独自メソッドも記述できる。

  • {{ 〇〇 }}
    → dataのmessageにアクセス
    →dataのmessageの値がマスタッシュ構文内のmessageに代入される。
    {{ data.message }}ではなく{ message }と記述することに注意。

<div id='app'>
    {{ message }}
</div>

<script>
 new Vue({
   el: '#app',
   data: {
     message: 'Hello World!'
   }
 })
</script>

当たり前だけど、以下はHTMLではなくテンプレート(v-forとかもテンプレート)を書いている。そしてVueがテンプレートの記述を見て「あ、これはテンプレート構文だ!」と判断して、HTMLに変換して出力してくれる。それをブラウザが受け取って画面に表示してくれるって感じ。

<div id='app'>
  {{ message }}
</div>

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

  • データと出力(描画)を同期する仕組み

  • 「v-」から始まるディレクティブ(命令)

v-bind

モジュールの値をコンポーネントに出力する。HTML要素のデータをバインドできる。
v-bind:引数="js側のプロパティ"という形で記述する。引数にはinputタグならvalue、aタグならhrefとか、タグにあった属性を記述する。
:引数="js側のプロパティ"に省略可能。

<div id="app">
  <input :value="message">
</div>

<script>
  new Vue({
    el: '#app',
        data: {
          message: 'Hello World!'
        }
  })

</script>

>> Hello World!

他にも[ ]を使った記述もできる。
Hello World!というリンクが表示される。

<div id="app">
  <!-- <a href='https:google.com'> と同じ --!>
  <a :[attribute]="url">Twitter</a>
</div>
<script>
  new Vue({
    el: '#app',
        data: {
          url: 'https://google.com',
          attribute: 'href'
        }
  })
</script>
>> Hello World!

更にv-bindでバインドする内容をオブジェクト形式で記述できる。

<div id="app">
  <!-- <a href='https://twitter.com', id=21> と同じ --!>
  <a v-bind="{href: urlTwitter, id: number}">Twitter</a>
</div>
<script>
  new Vue({
    el: '#app',
        data: {
          urlTwitter: 'https://twitter.com',
          number: 21
        }
  })
</script>

更にVue側にオブジェクトの中身を記述することもできる。

<div id="app">
  <!-- <a href='https://twitter.com', id=21> と同じ --!>
  <a v-bind="twitterObject">Twitter</a>
</div>
<script>
  new Vue({
    el: '#app',
        data: {
           twitterOblect: {
             href: 'https://twitter.com',
             id: 21
        }
  })
</script>

v-ifディレクティブ

HTMLの要素を表示、非表示
→非表示の時、要素ごと消える(DOMレベルで削除)
→表示で要素を再構築

<div id="app">
  <h1 v-if="flag">Vue is Good!</h1>
  <h1 v-else>Vue is Bad!</h1>
</div>
<script>
  new Vue({
    el: '#app',
    data: {
      flag: true
    }
  })
</script>

v-forディレクティブ

ループ処理

<タグ名 v-for="変数名 in 配列名"> {{ 変数名 }} </タグ名>

data内に記述した配列の要素が{{ item }}に代入される。 data内の配列がelによって#appと紐づいて、v-forでdata内の要素が順にitemに代入されるって感じ。

<ul id="app">
  <li v-for="item in list">{{ item }}</li>
</ul>

<script>
  new Vue({
    el: '#app',
        data: {
          list: ['Vue', 'React', 'Angular']
        }
  })
</script>

v-on

v-on:click@clickに省略できる

<タグ名 v-on: イベント名 = "ハンドラ名"> 表示したい文字 </タグ名>

methods: {
  ハンドラ名: 関数名() {
    処理
  }
}

これでクリックするたびに数値がカウントされていく

<div id="app">
  <span>{{ count }}</span>
  <button @click="increment">+</button>  ← +ボタン
</div>
  
<script>
  new Vue({
    el: '#app',
        data: {
          count: 0
        },
        methods: {
          increment: function() {
            this.count++
          }
        }
  })
</script>

ついでに

双方向バインディングとは

v-bindだと、HTML側の値を変更したとしても、モジュールの値は変更されない。

そこで双方向バインディングを使えば、プレビュー(HTML)側で入力した内容が、モジュール側の値を変更してくれる。
→入力内容を変更したことでデータの更新がなされ、DOMに反映される。

v-model ディレクティブ

v-bindとv-onの2つの処理を組み合わせたもの。
- inputにv-model="message"
→inputのフォームに入力した値が{{ message }}に結びつく。

<タグ名 v-model = "プロパティ名">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app">
  <p>{{message}}</p>
  <input v-model="message">
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      message: 'Hello World!'
    }
  })
</script>

<input v-model="message">data: { message: 'Hello World!' }Hello worldが入ってて、{{message}}にHello worldが表示される。
→inputを書き換えると{{message}}も書き換わる

component

Webサイトの画面はヘッダー、メイン、フッター、サイドバーなど色々な部品から構成される。 コンポーネントを使えば、部品ごとにHTML, CSS, JSを1セットにできる。
→変更箇所の発見、メンテナンスが容易になる、

Vue.component('コンポーネント名', {コンポーネントのオブジェクト})

Vue.component('my-component', { template: '<li>Hello World!</li>'})

コンポーネントは再利用が可能

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<div id="app">
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>
</div>

<script>
  Vue.component('my-component', {
    template: '<li>Hello World!</li>'
  })
  
  new Vue({
    el: '#app'
  })
</script>

>>
・ Hello World!
・ Hello World!
・ Hello World!

コンポーネントの親子間のデータの受け渡し

<div id="app">
  <my-component :message="'hoge'"></my-component>
  <my-component :message="'fuga'"></my-component>
  <my-component :message="'hogefuga'"></my-component>
</div>

<script>
  Vue.component('my-component', {
    props: ['message'],
    template: '<li>{{ message }} </li>'
  })
  
  new Vue({
    el: '#app'
  })
</script>


>> 
・hoge
・fuga
・hogefuga