iimon TECH BLOG

iimonエンジニアが得られた経験や知識を共有して世の中をイイモンにしていくためのブログです

vue双方向データバインディングを実現する仕組み

はじめに

はじめまして、株式会社iimonに4月入社した、フロントエンジニア担当しているみやこしです🍤

みなさんはvueを触るときになぜデータに入力した値がリアルタイムで画面に反映されるか疑問に感じたことありませんか。vueではこのようなことを双方向データバインディングと言います 今回は「vueの双方向データバインディング」はどのように実現しているのかについて話します!

object.defineproperty()

  • まず初めにobject.definepropertyについて紹介します

Object.defineProperty() は静的メソッドで、あるオブジェクトに新しいプロパティを直接定義したり、オブジェクトの既存のプロパティを変更したりして、そのオブジェクトを返します。

Object.defineProperty() を使うと1つのオブジェクトを通して別オブジェクトの操作(書き取り/読み取り)ができます

Object.defineProperty() - JavaScript | MDN

Object.defineProperty(<対象となるオブジェクト>, <プロパティ名>, <プロパティの詳細>)
  • object.definepropertyで定義したプロパティは列挙できず、プロパティの書き換えを防ぐことができます また以下のオプションキーを持ちます

    1.writable: Boolean / 変更可能 defaultはfalse

    2.enumerable: Boolean / 列挙可能 defaultはfalse

    3.configurable : Boolean / 削除可能 defaultはfalse

  • object.definepropertyはアクセサー記述子は以下の二つのオプションキーを持ちます

    1.get:プロパティが読み込まれた時に動作する

    2.set:プロパティがセットされた時に呼ばれる

  • Object.defineProperty() を使った例

getter:

      let obj1 = { a: 10 };
      let obj2 = { b: 20 };
      Object.defineProperty(obj2, "a", {
        get() {
          console.log("get");
          return obj1.a;
        },

上記の例ではobj2を介してobj1のプロパティを操作していることがわかります aのプロパティを参照する時、返ってくるのはgetterの戻り値である、つまりaの値である。aを参照するたびに、getter関数が呼び出されます。

setter:

      let obj1={a:10};
      let obj2={b:20};
     Object.defineProperty(obj2,'a',{
        get(){
          console.log('get');
          return obj1.a;
        },
        set(value){
          console.log('set');
          obj1.a=value;
        }
     });

上記の例からobj2のaの値が変わると、obj1の値も更新されることがわかります。

vue双方向データバインディングを実現する原理

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./vue.js"></script>
  </head>
  <body>
    <div id="root">
      <h2>名前:{{name}}</h2>
      <h2>年齢:{{age}}</h2>
    </div>
    <script>
      //例3
     const vm= new Vue({
        el:'#root',
        data:{
          name:'まり',
          age:18
        },
      })
    </script>
  </body>
</html>

上記のコード例からvmの中身を見ると、vmのオブジェクトを通してdataのオブジェクトを操作していることがわかります。

vueデータ反映するまでの過程

まとめ

vueの双方向データバインディングはobject.defineproperty()を用いて実現していることがわかった。 object.defineproperty()を通してdataオブジェクトの中のすべてのプロパティをvmの中に取り込み、そしてvmの中のすべてのプロパティにそれぞれgetterとsetterを指定し、getterとsetterの内部からdataオブジェクトの中のプロパティを操作している。

最後に

今回の勉強を通してvueに対する理解がさらに深めたと感じました!

最後までご覧いただき、ありがとうございます!

弊社ではエンジニアを募集しております。興味を持って下さった方がいらっしゃれば、是非カジュアル面談でお話ししましょう!

Wantedly / Green