プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • Vue.js
  • 【Vue.js】Vue.jsの設計思想(リアクティブシステム、データバインディング機能、仮…
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【Vue.js】Vue.jsの設計思想(リアクティブシステム、データバインディング機能、仮想DOMなど)

07.08

  • miyabisan2
  • コメントを書く

この記事は4分で読めます

Vue.jsのコンセプト~その1~:プログレッシブフレームワーク

「どんな時でも、どんな規模でも柔軟に使えるべき。」という思想になっています。アプリケーションの段階的な要求変化に応じて問題解決する方法を提供することが可能です。最初は小規模でも必要になった際に適切なライブラリやツールを導入することで大きく対応できるという柔軟さを持ちます。

Vue.jsのコンセプト~その2~:「データ駆動」になっていること。

データメインで考える設計思想になっています。

データバインディング機能、リアクティブシステム

JavaScriptのデータを書き換えるだけで、描画内容(DOM)も書き換わる仕組みのことです。Vue.jsが備えているリアクティブシステムという仕組みによって実現されています。(リアクティブシステムはデザインパターンのオブザーバパターンを元に設計されています。)リアクティブシステムの監視下におかえれたデータのことをリアクティブデータと呼びます。JavaScriptのデータを書き換えるだけで、描画内容も書き換わる仕組みのことで、テンプレートで定義しているデータの内容をHTMLタグ(CSSや、属性等)に紐付けることができます。

リアクティブシステムの実装方法

「算出プロパティ」と「ウォッチャ(Watcher)」の組み合わせによって実現します。

リアクティブシステムの仕組み

後で追加したプロパティはリアクティブにはならない。

下記のように後でVueインスタンスにプロパティを追加することもできます。ただdataに記述していないデータの場合はVueインスタンスを直接覗いてみれば分けると思いますが、セッターとゲッターが付加されていないのでリアクティブデータにはなりません。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  <script src="vue.js"></script>
 
  <div id="app2">
    <p>{{ message }}</p>
    <p>{{ name }}</p>
    <button @click="message='変更'">messageボタン</button><!-- 変更できる。-->
    <button @click="name='変更'">nameボタン</button> <!-- 変更できない。-->
  </div>
 
  <script>
    var vm2 = new Vue({
      el: "#app2",
      data: {
        message: "テスト"
      }
    })
 
    vm2.message = "変更します";
    vm2.name = "太郎";
 
  </script>
 
  <style>
    .red {
      color: #ff0000;
    }
 
    .yellow {
      background-color: #ffff00;
    }
  </style>

基本的には、データをリアクティブデータとして運用する事がVue.jsの基本になるのでdataに記述するようにしましょう。

外から渡すことは可能

ただ、下記のようにVueインスタンス外に定義されているデータをVueインスタンス内に渡してデータ内容として定義する事は可能になります。ややこしいですが、このような仕様になっています。

1
2
3
4
5
6
7
8
    const txt = "テキスト";
    let vm2 = new Vue({
      el: "#app2",
      data: {
        message: "テスト",
        text: txt
      }
    })

データバインディングを行うには?

使用する全てのデータを「リアクティブデータ」として定義する必要があります。

リアクティブデータとは?

Vue.jsによって、データを取得や設定した際に、反応できるデータのことです。

データバインディングを行うには?

テキストのバインディングには、Mustache(マスタッシュ)という記法を使う。

「{{}}」(二重括弧)を使ったMustache(マスタッシュ)という表記法で、テキストデータをバインディングできます。

v-bindを使う。

ディレクティブ「v-bind」を使います。属性や、CSSのバインディングを行うことができます。

修飾子 説明
.prop 属性の代わりに、DOMプロパティとしてバインドする。
.camel ケバブケースの属性名をキャメルケースとしてバインドする。
.sync 双方向バインディングを行う。
v-modelを使う。

v-modelを使うことで、下記二つの処理を同時に行うことができます。

  • データバインディングで、要素のvalueの値を更新する。
  • イベントハンドリングで、受け取った値を、データに代入する。

仮想DOM

リアクティブデータに基づいてVueがメモリ上に構築するDOMになります。DOMを象ったJavaScriptのオブジェクトになります。

仮想DOMにより、データ内容の差分だけを差し替えています。これにより、レンダリングスピードを大幅に向上させています。仮想DOMを作るために、「v-if」等の「テンプレート」記法を採用しています。

なぜ仮想DOMを使うのか?

DOMに要素を追加したりするのは実際のブラウザに存在するDOMを操作することになるので非常にコストがかかって遅くなります。部分的にDOMの要素を変更するに当たっても実際のDOMではなく、DOMを象ったJavaScriptのオブジェクトなのでかなり高速にデータ処理をする事が可能になります。

仕組み

「前回まで表示していた仮想DOM」と「今回変更した仮想DOM」をどちらもJavaScriptコード内で保持しておいて差分を比較しています。

$mount('el')

仮想DOMを実際のブラウザのDOMに反映させます。

Vue.jsのコンセプト~その3~:「コンポーネント指向」になっていること。

サイトの規模がおおきくなると、HTML/CSS/JavaScriptコードの管理が乱雑になってしまいます。

Vue.jsでは、機能ごとにCSS、JavaScriptとテンプレートを1つのセットにして、管理しているので、ソースを探しやすいです。

もちろん、ヘッダー、フッター等の共通化するコンポーネントも使うことができます。

Vue.jsのコンセプト~その4~:「MVVMモデル」になっていること。

MVCから派生したMVVM(Model-View-ViewModel)のアーキテクチャになっています。

ViewModel(ビューモデル)

ViewとModel(バインディングデータ)を仲介する役割でMVCで言えばコントローラ的な役割です。ただ、MVCでいうコントローラは描画処理には介入しないですが、ViewModelはデータバインディングを通じてモデルとビューを自動的に結びつけます。

テンプレートとは?

Vue.jsにて、DOMを構築する手段のことです。

テンプレートの構文は、HTMLベースになっているため、エディタとの親和性が高く、エンジニアとデザイナーの共同作業に向いています。

ディレクティブとは?

ディレクティブとは、「v-~」で始まる特別な属性のことで、「テンプレート」と「ロジック」を紐づけることができます。

Vue.jsでは、「ディレクティブ」を使ってテンプレートと連携します。(要は、データバインディングです。)

ディレクティブの種類

ディレクティブ 説明
v-for 繰り返し描画できます。
v-on クリックした際の動作を定義できます。
v-model データとフォームの入力項目をバインドできます。
v-if 条件分岐です。
v-text dataにアクセスします。配下の要素まで置き換わるので注意です。
{...} dataにアクセスします。「v-text」と似ていますが、配下の要素にアクセスはしません。
v-pre  {...}を無効化します。
v-bind コンポーネントのデータとHTML要素を同期させます。(バインディング)
v-html 画面にそのままhtmlタグを適用して出力させる事ができます。なので、v-textではできない文書内での改行の出力なんかに使われていたりします。
key 単なる文字列を表します。

ディレクティブの使い方

構文

1
ディレクティブ :引数 修飾子 = 値(JavaScriptの式)

具体例

1
v-bind :atai .sync = "test"

v-htmlとは?

画面にそのままhtmlタグを適用して出力させる事ができます。なので、v-textではできない文書内での改行の出力なんかに使われていたりします。

注意点

タグを解釈して実行させることになるので、JavaScriptコードを実行するXSSの脆弱性にもつながってしまいます。なので、v-htmlを利用する際は必ずユーザーからの入力をそのまま出力させるようなコードにはならないようにしましょう。

renderとは?

Vue.jsでレンダリングの制御ができる機能のことです。

renderの使い方

1
2
3
4
5
6
7
8
9
<render method="レンダリング関数名" :args="引数"></render>
 
new Vue({
  methods:{
    レンダリング関数:function(args){
      return arg
    }
  }
})

「renderタグ」を使って、その属性の中で「レンダリング関数」を呼ぶ必要があります。

レンダリング関数

レンダリングをする内容を返す必要があります。

レンダリング内容を生成する。

第一引数にタグ名、第二引数にタグ内容を指定すれば動的にタグを生成することも可能です。下記を実行すると<div id="app2">の中にpタグが生成されます。なお、下記の例ではレンダリング関数名を「args」としていますが、実際には「h」と記載されることも多いです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  <div id="app2">
  </div>
 
  <script>
    const txt = "テキスト";
    new Vue({
      el: '#app2',
      data: {
        message: "テスト",
        text: txt
      },
      render: function (args) {
        return args('p', 'レンダーテスト');
 
      }
    })
 
  </script>

レンダリング関数で返されている値について

VNodeという仮想DOMが返されています。

引数にオブジェクトも取れる。

下記はES6の記述方法になっていますが、render関数の引数にはオブジェクト(App.vueというオブジェクト)も取れます。

1
2
3
4
5
6
7
8
import Vue from 'vue'
import App from './App.vue'
 
Vue.config.productionTip = false
 
new Vue({
  render: h => h(App),
}).$mount('#app')

スポンサーリンク
  • 2018 07.08
  • miyabisan2
  • コメントを書く
  • Vue.js
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2020 04.12

    【Vue.js】コンポーネントから「Vuex」を呼び出す。

  2. 2018 07.16

    【Vue.js】「v-model」、コンポーネント間でv-modelを使う方法

  3. 2018 07.16

    【Vue.js】「コンポーネントの親子関係」について

  4. 2020 04.11

    【Vue.js】コンポーネントの設計について(Atomic Design等)

  5. 2018 07.16

    【Vue.js】「スロット」を使ったコンポーネントのカスタマイズについて

  6. 2018 07.17

    【Vue.js】「Vue Router」の基本、「Vuex」と連携してルーティング情報を一元管理

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【JavaScript】「クロージャ」について

【JavaScript】「ECMAScript2015…

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー