ホームページ  >  記事  >  ウェブフロントエンド  >  Vue を使用してプロパティの変更を観察する

Vue を使用してプロパティの変更を観察する

高洛峰
高洛峰オリジナル
2016-11-22 11:39:131032ブラウズ

応答システムは Vue の重要な機能であり、プロパティを変更するとビューを更新できるため、状態管理が非常にシンプルかつ直感的になります。
Vue インスタンスを作成するとき、Vue はデータのプロパティを走査し、ES5 の Object.defineProperty を通じてそれらをゲッター/セッターに変換します。内部的には、Vue は依存関係を追跡し、変更を通知できます。

const vm = new Vue({
  data: {foo: 1} // 'vm.foo' (在内部,同 'this.foo') 是响应的
})

プロパティの変更を監視する

Vue のインスタンスは、プロパティの変更を監視するための $watch メソッドを提供します。

const vm = new Vue({
  data: {foo: 1}
})

vm.$watch('foo', function (newValue, oldValue) {
  console.log(newValue, oldValue) // 输出 2 1
  console.log(this.foo) // 输出 2
})

vm.foo = 2

プロパティが変更されると、応答関数が呼び出され、内部的には自動的に Vue インスタンス vm にバインドされます。
応答は非同期であることに注意してください。以下の通り:

const vm = new Vue({
  data: {foo: 1}
})

vm.$watch('foo', function (newValue, oldValue) {
  console.log('inner:', newValue) // 后输出 "inner" 2
})

vm.foo = 2
console.log('outer:', vm.foo) // 先输出 "outer" 2

は $watch Vue を通じてデータとビューのバインディングを実現します。データ変更が検出されると、Vue は同じイベント ループ内で DOM を非同期的に更新し、次のイベント ループでキューを更新し、必要な更新のみを実行します。以下の通り:

const vm = new Vue({
  data: {foo: 1}
})

vm.$watch('foo', function (newValue, oldValue) {
  console.log('inner:', newValue) // 后只输出一次 "inner" 5
})

vm.foo = 2
vm.foo = 3
vm.foo = 4
console.log('outer:', vm.foo) // 先输出 "outer" 4
vm.foo = 5

計算されたプロパティ

MV* モデルレイヤーデータをビューに表示する場合、多くの場合、複雑なデータ処理ロジックが存在します。この場合、計算されたプロパティを使用する方が賢明です。

const vm = new Vue({
  data: {
    width: 0,
    height: 0,
  },
  computed: {
    area () {
      let output = ''
      if (this.width > 0 && this.height > 0) {
        const area = this.width * this.height
        output = area.toFixed(2) + 'm²'
      }
      return output
    }
  }
})

vm.width = 2.34
vm.height = 5.67
console.log(vm.area) // 输出 "13.27m²"

計算プロパティ内では、これは自動的に vm にバインドされるため、計算プロパティを宣言するときにアロー関数の使用を避ける必要があります。
上記の例では、vm.width と vm.height が応答します。vm.area が初めて this.width と this.height を読み取るとき、Vue はそれらを vm.area の依存関係として収集します。 vm.高さが変更されると、vm.area が再評価されます。
計算されたプロパティは、その依存関係キャッシュに基づいています。vm.width と vm.height が変更されない場合、vm.area を複数回読み取ると、再評価することなく、前の計算結果がすぐに返されます。
同様に、vm.width と vm.height は応答性があるため、依存するプロパティを vm.area の変数に割り当て、変数を読み取ることで、プロパティを読み取る回数を減らすことができます。同時に、Vue は条件付き分岐でプロパティを読み取ります。依存関係を収集できない場合があります。
新しい実装は次のとおりです:

const vm = new Vue({
  data: {
    width: 0,
    height: 0,
  },
  computed: {
    area () {
      let output = ''
      const {width, height} = this
      if (width > 0 && height > 0) {
        const area = width * height
        output = area.toFixed(2) + 'm²'
      }
      return output
    }
  }
})

vm.width = 2.34
vm.height = 5.67
console.log(vm.area) // 输出 "13.27m²"

ob.js を通じて Vue の属性観察モジュールを単独で使用します

学習と使用を容易にするために、ob.js は Vue の属性観察モジュールを抽出してカプセル化します。

インストール

npm install --save ob.js

プロパティの変更を観察

const target = {a: 1}
ob(target, 'a', function (newValue, oldValue) {
  console.log(newValue, oldValue) // 3 1
})
target.a = 3

計算されたプロパティを追加

const target = {a: 1}
ob.compute(target, 'b', function () {
  return this.a * 2
})
target.a = 10
console.log(target.b) // 20

Vueインスタンスを宣言するのと同じようにパラメータセットを渡します

const options = {
  data: {
    PI: Math.PI,
    radius: 1,
  },
  computed: {
    'area': function () {
      return this.PI * this.square(this.radius)
    },
  },
  watchers: {
    'area': function (newValue, oldValue) {
      console.log(newValue) // 28.274333882308138
    },
  },
  methods: {
    square (num) {
      return num * num
    },
  },
}
const target = ob.react(options)
target.radius = 3


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。