日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

vue 双向数据绑定的实现学习(一)

發布時間:2025/3/14 vue 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue 双向数据绑定的实现学习(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:本系列學習筆記從以下幾個點展開

  • 什么是雙向數據綁定
  • 雙向數據綁定的好處
  • 怎么實現雙向數據綁定
    • 實現雙向數據數據綁定需要哪些知識點
      • 數據劫持
      • 發布訂閱模式

?先看看我們要實現的目標是什么,如下動圖:

0、什么是雙向數據綁定

  單向數據綁定:把Model?綁定到View上,當我們用js修改模型?Model 時候,視圖View上對應的內容也會改動,這就是 數據動,頁面動 。

  雙向數據綁定:簡言之?數據動?頁面動,頁面動,數據動,?典型的應用就是在做表單時候,輸入框的內容改動后,跟該輸入框的value?的值改動。

  

看vue?官網上的這個V-model? 的演示案例:

?

1、雙向數據綁定的好處

  要說出這個好處的時候,也只有在實際場景中才能對應的顯示出來。比如我們需要實時顯示數據,我們一邊說話,一邊實時顯示我們說的話的文字內容,等等。這讓我想起了去年參加云棲大會,臺上的大佬一邊說話,下面的字幕實時更新。(當然實現這個技術有很多技術點,我們不討論這個內容,小編也才疏學淺,搞不懂)

以上的都是廢話,我們直接看看怎么實現這個雙向數據綁定。

一、實現原理

  Vue實現雙向數據綁定的原理:數據劫持 +?發布訂閱模式(有的也稱為觀察者模式)

  數據劫持的核心技術:?Object.defineProperty()

  **vue 3.0?已經用的不是這個技術了,采用是?原生的?Proxy,據說速度能夠提升100%,截張尤大的ppt,** 2018-11-21?修改本篇筆記

(香菇,剛研究會一點,就立馬變了,這就是前端世界),Proxy?的方式將會在本系列筆記結束后,再記錄這個技術點的使用

二、數據劫持的方法?Object.defineProperty()

  先上一個參照代碼,它長這個樣子:

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('重新設置_year了,并返回edition')
this.edition += newValue - 2004;}} }); book.year = 2005; alert(book.edition); //2

?---摘自 JavaScript高級程序設計

  Object.defineProperty()?的具體介紹,我們本文不做具體展開,查看我這里的一篇文章,Object.defineProperty。?我們這里先要知道這么一個事情。這個方法要傳入三個參數,傳入的數據對象data,屬性key,描述符對象。其中,描述符(descriptor)對象的屬 性必須是:configurable、enumerable、writable 和 value。設置其中的一或多個值,可以修改 對應的特性值。我們需要用的是這訪問器屬性。當我們在讀取訪問器屬性時,會調用 getter 函數,這個函數負責返回有效的值;在寫入訪問器屬性時,會調用 setter 函數并傳入新值,這個函數負責決定如何處理數據。上文代碼上的 get?方法,在讀取屬性時調用的函數,set方法,在寫入屬性時調用的函數。

三、發布訂閱者模式

  我畫了一個圖,來理解這個模式,如下圖:

  

?

代碼解釋:

//下面封裝一個單例模式,內容是發布訂閱模式 let event = {eventList: [],listener: function (key, fn) {if (!this.eventList[key]) { //沒有訂閱過此類消息,創建一個緩存列表this.eventList[key] = [];}this.eventList[key].push(fn)},trigger: function () {let key = Array.prototype.shift.call(arguments); // marrylet fns = this.eventList[key];if (!fns || fns.length == 0) { //沒有訂閱 則返回return false;}for (let i = 0, fn; fn = fns[i++];) {fn.apply(this, arguments)// 調用 event.listen 里面的 fn 方法,通過apply將當前執行的對象指向當前的this,arguments 傳進 fn 函數 }},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)// 上面方法 就會將event的方法 淺拷貝給 testMsg, 這樣testMsg就有 event的方法和屬性 testMsg.listener('rich', fn1 = (name) => {console.log(`${name}知道你有錢了`) }) testMsg.listener('borrowMoney', fn2 = (name) => {console.log(`${name}想問你借錢`) })// listen方法將事件 放進隊列 // testMsg.remove('rich', fn1) // 取消訂閱// trigger方法,處理事件隊列的方法,調用listen的函數的里面的回調函數 fn testMsg.trigger('rich', '張三') testMsg.trigger('rich', '張三2') testMsg.trigger('borrowMoney', '李四') testMsg.trigger('borrowMoney', '李四2')// 代碼總結: // 訂閱的事件具有對應的key// 通過listener方法,將具體的事件隊列保存到 eventList ,可以理解為緩存列表也可以是事件隊列;// 執行trigger 方法,將事件隊列拿出來執行調用// remove 方法根據對應的key值,刪除對應的訂閱事件 // 模式總結:封裝一個單例event, 執行installEvent方法,將想要event對象拷貝到某個對象中去, // 發布者trigger方法,監聽者listen方法 ,trigger 發布一個東西,listen立馬知道你要發布的東西 View Code

?

?

四、實現分解

  • 主函數入口
    •    function Myvue (options) {this.$options = optionsthis.$el = document.querySelector(options.el);this.$data = options.data;Object.keys(this.$data).forEach(key => {this.$prop = key;})this.init() } Myvue.prototype.init = function () {// 監聽數據變化observer(this.$data);// 獲得值// let value = this.$data[this.$prop];// 不經過模板編譯直接 通知訂閱者更新dom// new Watcher(this,this.$prop,value => {// console.log(`watcher ${this.$prop}的改動,要有動靜了`)// this.$el.textContent = value// }) //通知模板編譯來執行頁面上模板變量替換new Compile(this) }

      ?

  • 主函數調用
    •    <script>const vm = new Myvue({el: "#app",data: {name: "vue 雙向數據綁定test1"}}); </script>

      ?

  • 監聽器
  • 訂閱者
  • 模板編譯器

?未完待續,錯誤之處,敬請指出,共同進步!

下一篇?vue 雙向數據綁定的實現學習(二)-監聽器的實現

文章參考:

  https://www.cnblogs.com/beevesnoodles/p/9844854.html

  https://github.com/youngwind/blog/issues/87

  https://juejin.im/post/5a9108b6f265da4e7527b1a4

后記:代碼只做基本實現,不做代碼健壯性處理,一些錯誤處理已經忽略

轉載于:https://www.cnblogs.com/adouwt/p/9928278.html

總結

以上是生活随笔為你收集整理的vue 双向数据绑定的实现学习(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。