摘要:雙向數(shù)據(jù)綁定簡(jiǎn)言之?dāng)?shù)據(jù)動(dòng)頁面動(dòng),頁面動(dòng),數(shù)據(jù)動(dòng)典型的應(yīng)用就是在做表單時(shí)候,輸入框的內(nèi)容改動(dòng)后,跟該輸入框的的值改動(dòng)??垂倬W(wǎng)上的這個(gè)的演示案例雙向數(shù)據(jù)綁定的好處要說出這個(gè)好處的時(shí)候,也只有在實(shí)際場(chǎng)景中才能對(duì)應(yīng)的顯示出來。
前言:本系列學(xué)習(xí)筆記從以下幾個(gè)點(diǎn)展開
什么是雙向數(shù)據(jù)綁定
雙向數(shù)據(jù)綁定的好處
怎么實(shí)現(xiàn)雙向數(shù)據(jù)綁定
實(shí)現(xiàn)雙向數(shù)據(jù)數(shù)據(jù)綁定需要哪些知識(shí)點(diǎn)
數(shù)據(jù)劫持
發(fā)布訂閱模式
先看看我們要實(shí)現(xiàn)的目標(biāo)是什么,如下動(dòng)圖:
0、什么是雙向數(shù)據(jù)綁定單向數(shù)據(jù)綁定:把Model 綁定到View上,當(dāng)我們用js修改模型 Model 時(shí)候,視圖View上對(duì)應(yīng)的內(nèi)容也會(huì)改動(dòng),這就是 數(shù)據(jù)動(dòng),頁面動(dòng) 。
雙向數(shù)據(jù)綁定:簡(jiǎn)言之 數(shù)據(jù)動(dòng) 頁面動(dòng),頁面動(dòng),數(shù)據(jù)動(dòng), 典型的應(yīng)用就是在做表單時(shí)候,輸入框的內(nèi)容改動(dòng)后,跟該輸入框的value 的值改動(dòng)。
看vue 官網(wǎng)上的這個(gè)V-model 的演示案例:
1、雙向數(shù)據(jù)綁定的好處要說出這個(gè)好處的時(shí)候,也只有在實(shí)際場(chǎng)景中才能對(duì)應(yīng)的顯示出來。比如我們需要實(shí)時(shí)顯示數(shù)據(jù),我們一邊說話,一邊實(shí)時(shí)顯示我們說的話的文字內(nèi)容,等等。這讓我想起了去年參加云棲大會(huì),臺(tái)上的大佬一邊說話,下面的字幕實(shí)時(shí)更新。(當(dāng)然實(shí)現(xiàn)這個(gè)技術(shù)有很多技術(shù)點(diǎn),我們不討論這個(gè)內(nèi)容,小編也才疏學(xué)淺,搞不懂)
以上的都是廢話,我們直接看看怎么實(shí)現(xiàn)這個(gè)雙向數(shù)據(jù)綁定。
一、實(shí)現(xiàn)原理Vue實(shí)現(xiàn)雙向數(shù)據(jù)綁定的原理:數(shù)據(jù)劫持 + 發(fā)布訂閱模式(有的也稱為觀察者模式)
數(shù)據(jù)劫持的核心技術(shù): Object.defineProperty()
vue 3.0 已經(jīng)用的不是這個(gè)技術(shù)了,采用是 原生的 Proxy,據(jù)說速度能夠提升100%,截張尤大的ppt,** 2018-11-21 修改本篇筆記
(香菇,剛研究會(huì)一點(diǎn),就立馬變了,這就是前端世界),Proxy 的方式將會(huì)在本系列筆記結(jié)束后,再記錄這個(gè)技術(shù)點(diǎn)的使用
二、數(shù)據(jù)劫持的方法 Object.defineProperty()先上一個(gè)參照代碼,它長這個(gè)樣子:
var book = { _year: 2004, edition: 1 }; Object.defineProperty(book, "year", { get: function(){ console.log("訪問year了,返回_year") return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; console.log("重新設(shè)置_year了,并返回edition") this.edition += newValue - 2004; } } }); book.year = 2005; alert(book.edition); //2
---摘自 JavaScript高級(jí)程序設(shè)計(jì)
Object.defineProperty() 的具體介紹,我們本文不做具體展開,查看我這里的一篇文章,Object.defineProperty。 我們這里先要知道這么一個(gè)事情。這個(gè)方法要傳入三個(gè)參數(shù),傳入的數(shù)據(jù)對(duì)象data,屬性key,描述符對(duì)象。其中,描述符(descriptor)對(duì)象的屬 性必須是:configurable、enumerable、writable 和 value。設(shè)置其中的一或多個(gè)值,可以修改 對(duì)應(yīng)的特性值。我們需要用的是這訪問器屬性。當(dāng)我們?cè)谧x取訪問器屬性時(shí),會(huì)調(diào)用 getter 函數(shù),這個(gè)函數(shù)負(fù)責(zé)返回有效的值;在寫入訪問器屬性時(shí),會(huì)調(diào)用 setter 函數(shù)并傳入新值,這個(gè)函數(shù)負(fù)責(zé)決定如何處理數(shù)據(jù)。上文代碼上的 get 方法,在讀取屬性時(shí)調(diào)用的函數(shù),set方法,在寫入屬性時(shí)調(diào)用的函數(shù)。
三、發(fā)布訂閱者模式 我畫了一個(gè)圖,來理解這個(gè)模式,如下圖:
代碼解釋:
//下面封裝一個(gè)單例模式,內(nèi)容是發(fā)布訂閱模式 let event = { eventList: [], listener: function (key, fn) { if (!this.eventList[key]) { //沒有訂閱過此類消息,創(chuàng)建一個(gè)緩存列表 this.eventList[key] = []; } this.eventList[key].push(fn) }, trigger: function () { let key = Array.prototype.shift.call(arguments); // marry let fns = this.eventList[key]; if (!fns || fns.length == 0) { //沒有訂閱 則返回 return false; } for (let i = 0, fn; fn = fns[i++];) { fn.apply(this, arguments) // 調(diào)用 event.listen 里面的 fn 方法,通過apply將當(dāng)前執(zhí)行的對(duì)象指向當(dāng)前的this,arguments 傳進(jìn) fn 函數(shù) } }, remove: function (key, fn) { // 取消訂閱 let fns = this.eventList[key]; if (!fns) { return false; } if(!fn) { fns && (fns.length = 0) } else { for (let l = fns.length-1; l>=0; l--) { let _fn = fns[l]; if( _fn === fn) { fns.splice(l, 1) } } } }, install: function (obj) { for (let i in this) { if (i === "install") { return false } obj[i] = this[i]; } } } let testMsg = {} event.install(testMsg) // 上面方法 就會(huì)將event的方法 淺拷貝給 testMsg, 這樣testMsg就有 event的方法和屬性 testMsg.listener("rich", fn1 = (name) => { console.log(`${name}知道你有錢了`) }) testMsg.listener("borrowMoney", fn2 = (name) => { console.log(`${name}想問你借錢`) }) // listen方法將事件 放進(jìn)隊(duì)列 // testMsg.remove("rich", fn1) // 取消訂閱 // trigger方法,處理事件隊(duì)列的方法,調(diào)用listen的函數(shù)的里面的回調(diào)函數(shù) fn testMsg.trigger("rich", "張三") testMsg.trigger("rich", "張三2") testMsg.trigger("borrowMoney", "李四") testMsg.trigger("borrowMoney", "李四2") // 代碼總結(jié): // 訂閱的事件具有對(duì)應(yīng)的key // 通過listener方法,將具體的事件隊(duì)列保存到 eventList ,可以理解為緩存列表也可以是事件隊(duì)列; // 執(zhí)行trigger 方法,將事件隊(duì)列拿出來執(zhí)行調(diào)用 // remove 方法根據(jù)對(duì)應(yīng)的key值,刪除對(duì)應(yīng)的訂閱事件 // 模式總結(jié):封裝一個(gè)單例event, 執(zhí)行installEvent方法,將想要event對(duì)象拷貝到某個(gè)對(duì)象中去, // 發(fā)布者trigger方法,監(jiān)聽者listen方法 ,trigger 發(fā)布一個(gè)東西,listen立馬知道你要發(fā)布的東西四、實(shí)現(xiàn)分解 主函數(shù)入口
function Myvue (options) { this.$options = options this.$el = document.querySelector(options.el); this.$data = options.data; Object.keys(this.$data).forEach(key => { this.$prop = key; }) this.init() } Myvue.prototype.init = function () { // 監(jiān)聽數(shù)據(jù)變化 observer(this.$data); // 獲得值 // let value = this.$data[this.$prop]; // 不經(jīng)過模板編譯直接 通知訂閱者更新dom // new Watcher(this,this.$prop,value => { // console.log(`watcher ${this.$prop}的改動(dòng),要有動(dòng)靜了`) // this.$el.textContent = value // }) //通知模板編譯來執(zhí)行頁面上模板變量替換 new Compile(this) }主函數(shù)調(diào)用
監(jiān)聽器
訂閱者
模板編譯器
未完待續(xù),錯(cuò)誤之處,敬請(qǐng)指出,共同進(jìn)步!
下一篇 vue 雙向數(shù)據(jù)綁定的實(shí)現(xiàn)學(xué)習(xí)(二)-監(jiān)聽器的實(shí)現(xiàn)
文章參考:
https://www.cnblogs.com/beeve...
https://github.com/youngwind/...
https://juejin.im/post/5a9108...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99557.html
摘要:儲(chǔ)存訂閱器因?yàn)閷傩员槐O(jiān)聽,這一步會(huì)執(zhí)行監(jiān)聽器里的方法這一步我們把也給弄了出來,到這一步我們已經(jīng)實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的雙向綁定了,我們可以嘗試把兩者結(jié)合起來看下效果。總結(jié)本文主要是對(duì)雙向綁定原理的學(xué)習(xí)與實(shí)現(xiàn)。 當(dāng)今前端天下以 Angular、React、vue 三足鼎立的局面,你不選擇一個(gè)陣營基本上無法立足于前端,甚至是兩個(gè)或者三個(gè)陣營都要選擇,大勢(shì)所趨。 所以我們要時(shí)刻保持好奇心,擁抱變化,...
摘要:的數(shù)據(jù)劫持版本內(nèi)部使用了來實(shí)現(xiàn)數(shù)據(jù)與視圖的雙向綁定,體現(xiàn)在對(duì)數(shù)據(jù)的讀寫處理過程中。這樣就形成了數(shù)據(jù)的雙向綁定。 MVVM由以下三個(gè)內(nèi)容組成 View:視圖模板 Model:數(shù)據(jù)模型 ViewModel:作為橋梁負(fù)責(zé)溝通View和Model,自動(dòng)渲染模板 在JQuery時(shí)期,如果需要刷新UI時(shí),需要先取到對(duì)應(yīng)的DOM再更新UI,這樣數(shù)據(jù)和業(yè)務(wù)的邏輯就和頁面有強(qiáng)耦合。 在MVVM中,U...
摘要:執(zhí)行的時(shí)候,會(huì)綁定上下文對(duì)象為組件實(shí)例于是中的就能取到組件實(shí)例本身,的代碼塊頂層作用域就綁定為了組件實(shí)例于是內(nèi)部變量的訪問,就會(huì)首先訪問到組件實(shí)例上。其中的獲取,就會(huì)先從組件實(shí)例上獲取,相當(dāng)于。 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得...
摘要:雙向數(shù)據(jù)綁定的核心和基礎(chǔ)是其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有和基于和發(fā)布者訂閱者模式,最終實(shí)現(xiàn)數(shù)據(jù)的雙向綁定。在這里把雙向數(shù)據(jù)綁定分為兩個(gè)流程收集依賴流程依賴收集會(huì)經(jīng)過以上流程,最終數(shù)組中存放列表,數(shù)組中存放列表。 Vue雙向數(shù)據(jù)綁定的核心和基礎(chǔ)api是Object.defineProperty,其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有Obderver、Dep和Watcher,基于d...
摘要:學(xué)習(xí)內(nèi)容,基本語法和概念,打包工具,實(shí)戰(zhàn)操作參考文獻(xiàn)官網(wǎng)官方資料庫全家桶全家桶文檔概念前端框架借助可以實(shí)現(xiàn)手機(jī)開發(fā)前端框架是一套構(gòu)造用戶界面的框架,只關(guān)于視圖層前端的主要工作室跟用戶界面打交道,中的,實(shí)現(xiàn)界面效果框架是為了提高開發(fā) 學(xué)習(xí)內(nèi)容 1,Vue基本語法和概念 2, 打包工具 Webpack , Gulp3,實(shí)戰(zhàn)操作 參考文獻(xiàn):官網(wǎng): https://cn.vuejs.org...
閱讀 1010·2023-04-25 14:45
閱讀 2790·2021-09-30 09:59
閱讀 3132·2021-09-22 15:48
閱讀 2432·2019-08-30 15:55
閱讀 3485·2019-08-30 15:44
閱讀 551·2019-08-29 14:07
閱讀 3420·2019-08-26 13:45
閱讀 545·2019-08-26 11:31