Vueソースコードの解読はどのように配列の変化を検出します
10605 ワード
前言
前回の記事では、Vue初期化dataの応答式の原理を知っています.オブジェクトが
まず、この判断
配列書き換えプロトタイプと観察者に更新を通知する場所配列プロトタイプを作成し、 に割り当てます.配列プロトタイプメソッドを を修正する.配列変化のデータを観測し,再帰的遍歴法実体を上に見る10行 . wachter更新ビュー に通知する.
まとめ
Vueはdata中の配列を関数ハイジャック方式でプロトタイプチェーン書き換えを行った.配列apiを呼び出すと依存更新を通知できるように、独自に定義された配列プロトタイプメソッドを指す.配列に参照タイプが含まれている場合.配列内の参照タイプが再監視されます.
前回の記事では、Vue初期化dataの応答式の原理を知っています.オブジェクトが
defineReactive
方法でdata属性をモニタリングする方法について説明しただけで、配列は少し持っているだけで、下のソースコードで撫でてみましょう.まず、この判断
src/core/observer/index.js
Observerクラス構築関数を参照してください.//
if (Array.isArray(value)) { //
if (hasProto) {
protoAugment(value, arrayMethods) //
} else {
copyAugment(value, arrayMethods, arrayKeys) //
}
this.observeArray(value) // , observeArray
} else {
this.walk(value) // ( )
}
}
protoAugment
プロトタイプ書き換え方法、プロトタイプ書き換えをarrayMethods
に向ける/**
* Augment a target Object or Array by intercepting
* the prototype chain using __proto__
*/
function protoAugment (target, src: Object) {
/* eslint-disable no-proto */
target.__proto__ = src
/* eslint-enable no-proto */
}
observeArray
は主に配列を遍歴し、observer
を呼び出してリスニングされたかどうかを判断し、リスニングされていない場合はnew Observer
がリスニングを作成し、前述した. /**
* Observe a list of Array items.
*/
observeArray (items: Array<any>) { // , observer
for (let i = 0, l = items.length; i < l; i++) {
observe(items[i]) //
}
}
配列書き換えプロトタイプと観察者に更新を通知する場所
src/core/observer/array.js
,jsファイル全体の内容は多くなく,主にいくつかのことをした.arrayMethods
arrayMethods
に書き換え、this observeArray
/*
* not type checking this file because flow doesn't play well with
* dynamically accessing methods on Array prototype
*/
import { def } from '../util/index'
const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto) // arrayMethods
const methodsToPatch = [ //
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
/**
* Intercept mutating methods and emit events
*/
methodsToPatch.forEach(function (method) {
// cache original method
const original = arrayProto[method]
def(arrayMethods, method, function mutator (...args) { //
const result = original.apply(this, args) // this
const ob = this.__ob__
let inserted
switch (method) {
case 'push':
case 'unshift':
inserted = args
break
case 'splice':
inserted = args.slice(2)
break
}
if (inserted) ob.observeArray(inserted) //
// notify change
ob.dep.notify() //
return result
})
})
まとめ
Vueはdata中の配列を関数ハイジャック方式でプロトタイプチェーン書き換えを行った.配列apiを呼び出すと依存更新を通知できるように、独自に定義された配列プロトタイプメソッドを指す.配列に参照タイプが含まれている場合.配列内の参照タイプが再監視されます.