摘要:的使用相信大家都很熟練了,使用起來(lái)簡(jiǎn)單。但是大部分人不知道其內(nèi)部的原理是怎么樣的,今天我們就來(lái)一起實(shí)現(xiàn)一個(gè)簡(jiǎn)單的實(shí)現(xiàn)之前我們得先看一下的實(shí)現(xiàn),因?yàn)橹饕峭ㄟ^(guò)數(shù)據(jù)劫持來(lái)實(shí)現(xiàn)的,通過(guò)來(lái)完成數(shù)據(jù)的讀取和更新。
vue的使用相信大家都很熟練了,使用起來(lái)簡(jiǎn)單。但是大部分人不知道其內(nèi)部的原理是怎么樣的,今天我們就來(lái)一起實(shí)現(xiàn)一個(gè)簡(jiǎn)單的vue
Object.defineProperty()實(shí)現(xiàn)之前我們得先看一下Object.defineProperty的實(shí)現(xiàn),因?yàn)関ue主要是通過(guò)數(shù)據(jù)劫持來(lái)實(shí)現(xiàn)的,通過(guò)get、set來(lái)完成數(shù)據(jù)的讀取和更新。
var obj = {name:"wclimb"} var age = 24 Object.defineProperty(obj,"age",{ enumerable: true, // 可枚舉 configurable: false, // 不能再define get () { return age }, set (newVal) { console.log("我改變了",age +" -> "+newVal); age = newVal } }) > obj.age > 24 > obj.age = 25; > 我改變了 24 -> 25 > 25
從上面可以看到通過(guò)get獲取數(shù)據(jù),通過(guò)set監(jiān)聽(tīng)到數(shù)據(jù)變化執(zhí)行相應(yīng)操作,還是不明白的話可以去看看Object.defineProperty文檔。
流程圖 html代碼結(jié)構(gòu)js調(diào)用{{form}}
new Vue({ el: "#wrap", data:{ form: "這是form的值", test: "我是粗體", }, methods:{ changeValue(){ console.log(this.form) this.form = "值被我改變了,氣不氣?" } } })Vue結(jié)構(gòu)
class Vue{ constructor(){} proxyData(){} observer(){} compile(){} compileText(){} } class Watcher{ constructor(){} update(){} }
Vue constructor 構(gòu)造函數(shù)主要是數(shù)據(jù)的初始化
proxyData 數(shù)據(jù)代理
observer 劫持監(jiān)聽(tīng)所有數(shù)據(jù)
compile 解析dom
compileText 解析dom里處理純雙花括號(hào)的操作
Watcher 更新視圖操作
Vue constructor 初始化class Vue{ constructor(options = {}){ this.$el = document.querySelector(options.el); let data = this.data = options.data; // 代理data,使其能直接this.xxx的方式訪問(wèn)data,正常的話需要this.data.xxx Object.keys(data).forEach((key)=> { this.proxyData(key); }); this.methods = options.methods // 事件方法 this.watcherTask = {}; // 需要監(jiān)聽(tīng)的任務(wù)列表 this.observer(data); // 初始化劫持監(jiān)聽(tīng)所有數(shù)據(jù) this.compile(this.$el); // 解析dom } }
上面主要是初始化操作,針對(duì)傳過(guò)來(lái)的數(shù)據(jù)進(jìn)行處理
proxyData 代理dataclass Vue{ constructor(options = {}){ ...... } proxyData(key){ let that = this; Object.defineProperty(that, key, { configurable: false, enumerable: true, get () { return that.data[key]; }, set (newVal) { that.data[key] = newVal; } }); } }
上面主要是代理data到最上層,this.xxx的方式直接訪問(wèn)data
observer 劫持監(jiān)聽(tīng)class Vue{ constructor(options = {}){ ...... } proxyData(key){ ...... } observer(data){ let that = this Object.keys(data).forEach(key=>{ let value = data[key] this.watcherTask[key] = [] Object.defineProperty(data,key,{ configurable: false, enumerable: true, get(){ return value }, set(newValue){ if(newValue !== value){ value = newValue that.watcherTask[key].forEach(task => { task.update() }) } } }) }) } }
同樣是使用Object.defineProperty來(lái)監(jiān)聽(tīng)數(shù)據(jù),初始化需要訂閱的數(shù)據(jù)。
把需要訂閱的數(shù)據(jù)到push到watcherTask里,等到時(shí)候需要更新的時(shí)候就可以批量更新數(shù)據(jù)了。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/97706.html
摘要:前言月份開(kāi)始出沒(méi)社區(qū),現(xiàn)在差不多月了,按照工作的說(shuō)法,就是差不多過(guò)了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了一般來(lái)說(shuō),差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議那么今天我就把看過(guò)的一些學(xué)習(xí)資源主要是博客,博文推薦分享給大家。 1.前言 6月份開(kāi)始出沒(méi)社區(qū),現(xiàn)在差不多9月了,按照工作的說(shuō)法,就是差不多過(guò)了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了!一般來(lái)說(shuō),差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議!那么今天我就...
平日學(xué)習(xí)接觸過(guò)的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...
平日學(xué)習(xí)接觸過(guò)的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...
閱讀 3155·2021-11-22 12:01
閱讀 3775·2021-08-30 09:46
閱讀 789·2019-08-30 13:48
閱讀 3219·2019-08-29 16:43
閱讀 1667·2019-08-29 16:33
閱讀 1855·2019-08-29 13:44
閱讀 1420·2019-08-26 13:45
閱讀 2237·2019-08-26 11:44