<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] ****** ## 4 [\core\observer\] 數據綁定目錄 >注:本節機制見基礎原理的數據綁定 ### 4-1 目錄文件 ~~~ \core\observer\ index.js ;數據監控器observer dep.js ;消息訂閱器 watcher.js ;消息訂閱者 batcher.js ;刷新 array.js ;數組監控 ~~~ ### 4-2 index.js(數據監控器) >[info] import ~~~ ;(導入) 消息訂閱器,數組監控器,基礎工具 import Dep from './dep' import { arrayMethods } from './array' import { def, remove, isArray, isObject, isPlainObject, hasProto, hasOwn, isReserved } from '../util/index' ~~~ >[info] module ~~~ ;數據監控方法鍵名 const arrayKeys = Object.getOwnPropertyNames(arrayMethods) ;是否需要遞歸轉換響應屬性 export const observerState = { shouldConvert: true } ;創建數據監視器 export function Observer (value) { this.value = value this.dep = new Dep() def(value, '__ob__', this) ;數組類型值監視 if (isArray(value)) { const augment = hasProto ? protoAugment : copyAugment augment(value, arrayMethods, arrayKeys) this.observeArray(value) } else { ;普通類型值監視 this.walk(value) } } ;普通數據遍歷轉換 Observer.prototype.walk = function (obj) { for (const key in obj) { this.convert(key, obj[key]) } } ;數組數據遍歷轉換 Observer.prototype.observeArray = function (items) { for (let i = 0, l = items.length; i < l; i++) { observe(items[i]) } } ;數據轉換為響應屬性 Observer.prototype.convert = function (key, val) { defineReactive(this.value, key, val) } ;添加數據監視器與vm關聯 Observer.prototype.addVm = function (vm) { (this.vms || (this.vms = [])).push(vm) } ;注銷數據監視器與vm關聯 Observer.prototype.removeVm = function (vm) { remove(this.vms, vm) } ;數組類型值參數proto實現 function protoAugment (target, src) { /* eslint-disable no-proto */ target.__proto__ = src /* eslint-enable no-proto */ } ;數組類型值參數copy實現 function copyAugment (target, src, keys) { for (let i = 0, l = keys.length; i < l; i++) { const key = keys[i] def(target, key, src[key]) } } ;創建數據的監視器并關聯vm export function observe (value, vm) { if (!isObject(value)) { return } let ob if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { ob = value.__ob__ } else if ( observerState.shouldConvert && (isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue ) { ob = new Observer(value) } if (ob && vm) { ob.addVm(vm) } return ob } ;創建對象的屬性位響應,這里實現數據雙向綁定 export function defineReactive (obj, key, val) { ;set操作消息訂閱數組 const dep = new Dep() ;檢查屬性的描述信息 const property = Object.getOwnPropertyDescriptor(obj, key) if (property && property.configurable === false) { return } // cater for pre-defined getter/setters const getter = property && property.get const setter = property && property.set let childOb = observe(val) ;生成響應屬性 Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () { ;獲取值 const value = getter ? getter.call(obj) : val ;是否需要添加到消息訂閱數組 if (Dep.target) { dep.depend() if (childOb) { childOb.dep.depend() } if (isArray(value)) { for (let e, i = 0, l = value.length; i < l; i++) { e = value[i] e && e.__ob__ && e.__ob__.dep.depend() } } } return value }, set: function reactiveSetter (newVal) { ;獲取值,并比較新舊值 const value = getter ? getter.call(obj) : val if (newVal === value) { return } ;值不同進行修改 if (setter) { setter.call(obj, newVal) } else { val = newVal } ;創建位數據監視器 childOb = observe(newVal) ;廣播到消息訂閱數組中 dep.notify() } }) } ;對象屬性修改快捷方式 export function set (obj, key, val) { ;數組類型值屬性修改 if (isArray(obj)) { return obj.splice(key, 1, val) } ;普通對象屬性值修改 if (hasOwn(obj, key)) { obj[key] = val return } ;Vue對象屬性值修改obj._data if (obj._isVue) { set(obj._data, key, val) return } ;響應數據值__ob__修改 const ob = obj.__ob__ if (!ob) { obj[key] = val return } ob.convert(key, val) ob.dep.notify() ;vms相應修改 if (ob.vms) { let i = ob.vms.length while (i--) { const vm = ob.vms[i] proxy(vm, key) vm.$forceUpdate() } } ;返回修改后的值 return val } ;刪除對象屬性快捷方法 export function del (obj, key) { ;普通對象 if (!hasOwn(obj, key)) { return } delete obj[key] ;響應對象 const ob = obj.__ob__ if (!ob) { if (obj._isVue) { delete obj._data[key] obj.$forceUpdate() } return } ob.dep.notify() if (ob.vms) { let i = ob.vms.length while (i--) { const vm = ob.vms[i] unproxy(vm, key) vm.$forceUpdate() } } } ;$與_數據代理模擬生成vm._data export function proxy (vm, key) { if (!isReserved(key)) { Object.defineProperty(vm, key, { configurable: true, enumerable: true, get: function proxyGetter () { return vm._data[key] }, set: function proxySetter (val) { vm._data[key] = val } }) } } ;數據代理注銷模擬 export function unproxy (vm, key) { if (!isReserved(key)) { delete vm[key] } } ~~~ >[info] export ~~~ ;(導出)數據監控器 export function Observer (value) {} ;(導出)數據監控注冊到vm export function observe (value, vm) {} ;(導出)生成響應屬性 export function defineReactive (obj, key, val) {} ;(導出)修改對象屬性 export function set (obj, key, val) {} ;(導出)刪除對象屬性 export function del (obj, key) {} ;(導出)屬性代理模擬 export function proxy (vm, key) {} ;(導出)屬性代理注銷模擬 export function unproxy (vm, key) {} ~~~ ![](https://box.kancloud.cn/2016-05-06_572bf787b395e.jpg) ### 4-3 dep.js(消息訂閱器) >[info] import ~~~ ;(導入)刪除數組項 import { remove } from '../util/index' ~~~ >[info] module ~~~ ;dep的id let uid = 0 ;Dep結構組織id和subs數組 export default function Dep () { this.id = uid++ this.subs = [] } ;消息訂閱數組狀態標志;用于綁定數據監視器 Dep.target = null ;消息訂閱數組添加消息訂閱者 Dep.prototype.addSub = function (sub) { this.subs.push(sub) } ;消息訂閱數組刪除消息訂閱者 Dep.prototype.removeSub = function (sub) { remove(this.subs, sub) } ;消息訂閱者添加到消息訂閱數組 Dep.prototype.depend = function () { Dep.target.addDep(this) } ;廣播消息訂閱數組用于刷新 Dep.prototype.notify = function () { const subs = this.subs.slice() for (let i = 0, l = subs.length; i < l; i++) { subs[i].update() } } ~~~ >[info] export ~~~ ;(導出)消息訂閱數組 export default function Dep () {} ~~~ ![](https://box.kancloud.cn/2016-05-06_572bf787b395e.jpg) ### 4-4 watcher.js(消息訂閱者) >[info] import >[info] module >[info] export ![](https://box.kancloud.cn/2016-05-06_572bf787b395e.jpg) ### 4-5 batcher.js(刷新) >[info] import ~~~ ;(導入)消息訂閱數組,刷新模塊,基礎工具 import Dep from './dep' import { pushWatcher } from './batcher' import { warn, remove, extend, isArray, isObject, parsePath, _Set as Set } from '../util/index' ~~~ >[info] module ~~~ ;uid,前一個Watcher let uid = 0 let prevTarget ;消息訂閱者 export default function Watcher (vm, expOrFn, cb, options) { ;初始化參數 if (options) { extend(this, options) } ;待解析表達式 const isFn = typeof expOrFn === 'function' ;vm與vm._watchers this.vm = vm vm._watchers.push(this) ;解析表達式 this.expression = expOrFn this.cb = cb ;uid this.id = ++uid // uid for batching ;狀態控制 this.active = true this.dirty = this.lazy // for lazy watchers ;Dep管理 this.deps = [] this.newDeps = [] this.depIds = new Set() this.newDepIds = new Set() ;表達式解析為getter if (isFn) { this.getter = expOrFn } else { this.getter = parsePath(expOrFn) if (!this.getter) { this.getter = function () {} process.env.NODE_ENV !== 'production' && warn( 'Failed watching path: ' + expOrFn + 'Watcher only accepts simple dot-delimited paths. ' + 'For full control, use a function instead.', vm ) } } ;值獲取 this.value = this.lazy ? undefined : this.get() this.queued = this.shallow = false } ;Watcher.get():watcher值獲取 Watcher.prototype.get = function () { ;get前回調 this.beforeGet() ;getter調用 const value = this.getter.call(this.vm, this.vm) ;遞歸調用 if (this.deep) { traverse(value) } ;get后回調 this.afterGet() ;返回獲取的值 return value } ;get前依Dep保存 Watcher.prototype.beforeGet = function () { prevTarget = Dep.target Dep.target = this } ;Watcher.addDep()添加Watcher到Dep Watcher.prototype.addDep = function (dep) { const id = dep.id if (!this.newDepIds.has(id)) { this.newDepIds.add(id) this.newDeps.push(dep) if (!this.depIds.has(id)) { dep.addSub(this) } } } ;get后dep恢復 Watcher.prototype.afterGet = function () { Dep.target = prevTarget let i = this.deps.length while (i--) { const dep = this.deps[i] if (!this.newDepIds.has(dep.id)) { dep.removeSub(this) } } let tmp = this.depIds this.depIds = this.newDepIds this.newDepIds = tmp this.newDepIds.clear() tmp = this.deps this.deps = this.newDeps this.newDeps = tmp this.newDeps.length = 0 } ;Watcher.update():watcher刷新 Watcher.prototype.update = function (shallow) { if (this.lazy) { this.dirty = true } else if (this.sync) { this.run() } else { this.shallow = this.queued ? shallow ? this.shallow : false : !!shallow this.queued = true ;添加到刷新隊列 pushWatcher(this) } } ;Watcher.run() 刷新過程 Watcher.prototype.run = function () { if (this.active) { const value = this.get() if ( value !== this.value ||((isObject(value) || this.deep) && !this.shallow) ) { const oldValue = this.value this.value = value this.cb.call(this.vm, value, oldValue) } this.queued = this.shallow = false } } ;Watcher.evaluate計算Watcher表達式的值 Watcher.prototype.evaluate = function () { const current = Dep.target this.value = this.get() this.dirty = false Dep.target = current } ~~~ >[info] export ~~~ ;(導出)消息訂閱者 export default function Watcher{} ~~~ ![](https://box.kancloud.cn/2016-05-06_572bf787b395e.jpg) ### 4-6 array.js(數組監控) >[info] import ~~~ ;(導入) 對象屬性定義 import { def } from '../util/index' ~~~ >[info] module ~~~ ;數組原型 const arrayProto = Array.prototype ;數組原型方法 export const arrayMethods = Object.create(arrayProto) ;方法修改 ;[ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ] .forEach(function (method) { ;原始方法 const original = arrayProto[method] ;注冊對象屬性為擴展方法 def(arrayMethods, method, function mutator () { ;參數獲取 let i = arguments.length const args = new Array(i) while (i--) { args[i] = arguments[i] } ;原始方法調用 const result = original.apply(this, args) ;數據監聽實現 const ob = this.__ob__ let inserted switch (method) { case 'push': inserted = args break case 'unshift': inserted = args break case 'splice': inserted = args.slice(2) break } ;數組數據監聽 if (inserted) ob.observeArray(inserted) ;依賴刷新 ob.dep.notify() ;返回結果 return result }) }) ~~~ >[info] export ~~~ ;(導出)數組方法 export const arrayMethods ~~~ ![](https://box.kancloud.cn/2016-05-06_572bf6c0146bf.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看