摘要:響應式原理作為寫業務的碼農,幾乎不必知道原理。所以找工作之前可以先復習下,只要是關于的,必定會問響應式原理。如果是,運行其方法,其方法中含有的值時,會觸發收集當更新時,也會觸發更新重新獲取值如果是會觸發的函數響應式原理計算屬性值這是
Vue響應式原理
作為寫業務的碼農,幾乎不必知道原理。但是當你去找工作的時候,可是需要造原子彈的,什么都得知道一些才行。所以找工作之前可以先復習下,只要是關于vue的,必定會問響應式原理。
核心:
//es5 Object.defineProperty(obj,key,{ get() { // 獲取obj[key]的時候觸發 }, set(val) { // obj[key] = "xxx"時觸發 } })
其實,只需要在修改data值的時候,需要觸發一個回調方法,來更新與此值有關的數據,就完了。但是你面試的時候,那些大佬可不會覺得是這樣的,需要把整個流程說明白才行。
簡單的Vue響應式代碼如下: Vue.js:class Vue { constructor(opts) { this.opts = opts if (opts.data) this.initData(opts.data); if (opts.watch) this.initWatch(opts.watch); if (opts.computed) this.initComputed(opts.computed); if (opts.el) this.$mount(opts.el) } initData(data) { // 讓data上的數據被get的時候能夠搜集watcher,data變為觀察者 new Observable(data); this.data = data // 數據可在this上直接讀取 Object.keys(data).forEach(key => { this.proxy(key) }) } initWatch(watch) { Object.keys(watch).forEach(key => { // new Watcher(this, key, watch[key]) }) } initComputed(data) { Object.keys(data).forEach(key => { new Watcher(this, key) this.proxy(key, { get: data[key], }) }) } $mount(el) { el = document.querySelector(el) this.template = el.innerHTML this.el = el const fn = _ => { const nwTemp = this.parseHTML(this.template) this.el.innerHTML = nwTemp if(this.opts.mounted) { this.opts.mounted.call(this) } } new Watcher(this, fn) } parseHTML(template) { return template.replace(/{{(.*?)}}/g, (str, str1) => { return this[str1.trim()] }) } // 將數據直接掛到this上,使用getterSetter代理,獲取vm.data上的值 proxy(key, getterSetter) { const vm = this getterSetter = getterSetter || { set(value) { vm.data[key] = value }, get() { return vm.data[key] } } Object.defineProperty(vm, key, getterSetter) } } // 給data作為觀察者用的 class Observable { constructor(obj) { Object.keys(obj).forEach(key => { this.defineReact(obj, key, obj[key]) }); } defineReact(obj, key, value) { const dep = new Dep() Object.defineProperty(obj, key, { get() { // 獲取data里面信息的時候,能夠搜集依賴,這些依賴都是watcher實例 if (Dep.target) { dep.append(Dep.target) } return value }, set(val) { value = val // 修改data里面數據的時候,去通知已搜集的依賴更新 dep.notify() } }) } } // 搜集與觸發wacher class Dep { constructor() { this.subs = [] } append(watcher) { // 避免重復添加watcher // watcher 在update的時候,會重新獲取值,此時不必再添加 if(this.subs.includes(watcher)) return this.subs.push(watcher) } notify() { this.subs.forEach(watcher => { watcher.update() }) } } Dep.target = null class Watcher { // keyOrFn 為字符串或者function,opts.watch為字符串,computed,$mount中為function constructor(vm, keyOrFn, cb) { this.cb = cb if (typeof keyOrFn === "string") { this.getter = function () { return vm[keyOrFn] // 例:initWatch時,watch:{a(){}} ,a為data里的數據,此處獲取vm.a會觸發a的收集 } } else { this.getter = keyOrFn // 如果為fn(computed中)值為此函數的返回值 } this.value = this.get() } get() { Dep.target = this // 此watcher記錄下來 const value = this.getter(this.vm) // 運行getter,如果是watch,獲取一次data里的值,完成收集。 // 如果是computed,運行其方法,其方法中含有data的值時,會觸發收集 // 當更新時,也會觸發getter Dep.target = null return value } update() { // 更新 const oldValue = this.value // 重新獲取值 this.value = this.get() if (this.cb) { //如果是watch,會觸發watch的函數 this.cb.call(this.vm, this.value, oldValue) } } }index.html
Vue響應式原理
msg: {{ msg }}
num: {{ num }}
num+1計算屬性值:{{ add1 }}
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/104174.html
摘要:工程實踐立足實踐,提示實際水平內聯函數與性能很多關于性能優化的文章都會談及內聯函數,其也是常見的被詬病為拖慢性能表現的元兇之一不過本文卻是打破砂鍋問到底,論證了內聯函數并不一定就會拖慢性能,過度的性能優化反而會有損于應用性能。 showImg(https://segmentfault.com/img/remote/1460000011481413?w=1240&h=825); 前端每周...
摘要:深入學習作為配合使用的數據狀態管理庫,針對解決兄弟組件或多層級組件共享數據狀態的痛點問題來說,非常好用。至此,構造函數部分已經過了一遍了。 深入學習Vuex vuex作為配合vue使用的數據狀態管理庫,針對解決兄弟組件或多層級組件共享數據狀態的痛點問題來說,非常好用。本文以使用者的角度,結合源碼來學習vuex。其中也參考了許多前輩的文章,參見最后的Reference Vue加載Vuex...
閱讀 3976·2021-11-18 13:22
閱讀 1813·2021-11-17 09:33
閱讀 2877·2021-09-26 09:46
閱讀 1208·2021-08-21 14:11
閱讀 2884·2019-08-30 15:53
閱讀 2707·2019-08-30 15:52
閱讀 1885·2019-08-30 10:52
閱讀 1517·2019-08-29 15:30