<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      馬扎糖女孩

      導航

      vue學習之深入響應式原理

      vue的響應式原理

        當你把一個普通的 JavaScript 對象傳入 Vue 實例作為 data 選項,Vue 將遍歷此對象所有的屬性,并使用 Object.defineProperty 把這些屬性全部轉為 getter/setter。

      Object.defineProperty 是 ES5 中一個無法 shim 的特性,這也就是 Vue 不支持 IE8 以及更低版本瀏覽器的原因。

      這些 getter/setter 對用戶來說是不可見的,但是在內部它們讓 Vue 能夠追蹤依賴,在屬性被訪問和修改時通知變更。每個組件實例都對應一個 watcher 實例,它會在組件

      渲染的過程中把“接觸”過的數據屬性記錄為依賴。之后當依賴項的 setter 觸發時,會通知 watcher,從而使它關聯的組件重新渲染。

       

      通過這么長時間的學習,我用比較直白的話來詳細的解釋一下原理

      首先咱們需要掌握兩個方法

      一個是Object.defineProperty,一個是訂閱者設計模式

      Object.defineProperty方法

      Object.defineProperty會直接在一個對象上定義一個新屬性或者修改一個對象的現有屬性,并且返回這個對象。

      Object.defineProperty(obj,prop,descriptor)有三個屬性。obj是要定義屬性的對象。prop是需要定義或者修改的屬性的名稱,descrptor是被定義或修改的屬性描述符。

      setter或者getter是js對象中用來設置屬性或獲取屬性的方法,他是在創建對象的時候指明的。

      當data對象中有值存在時,vue就會獲取這個對象,獲取這個對象的時候就會調用get,然后會用Object.keys()方法拿到這個data對象中的每個屬性,

      然后進行遍歷,得到每個屬性,然后通過Object.defineProperty的set和get方法進行設置屬性值或者是獲取屬性值。

       

      發布-訂閱模式

      舉個例子來說明一下發布者訂閱者模式。上面的例子中,就是讓張三和李四來訂閱了這個message屬性的改變。

      發布-訂閱是一種消息范式,消息的發送者(稱為發布者)不會將消息直接發送給特定的接收者(稱為訂閱者)。而

      是將發布的消息分為不同的類別,無需了解哪些訂閱者(如果有的話)可能存在。同樣的,訂閱者可以表達對一個或多個類別的興趣,

      只接收感興趣的消息,無需了解哪些發布者(如果有的話)存在。

      舉一個例子,你在微博上關注了A,同時其他很多人也關注了A,那么當A發布動態的時候,微博就會為你們推送這條動態。

      A就是發布者,你是訂閱者,微博就是調度中心,你和A是沒有直接的消息往來的,全是通過微博來協調的(你的關注,A的發布動態)。

      vue就是通過這種發布者訂閱者模式來處理響應式數據的。

       

      下面的代碼只是把整個響應式的過程解釋了一下,但是源碼并不是這么寫的,但是整個流程是這樣走滴,只不過我簡化可很多~~希望大家能明白哈

        // 他們全用了message
        <div>{{message}}</div>
          <p>{{message}}</p>
          <i>{{message}}</i>
       
         data() {
            return {
            message:'嘻嘻',
              name:'why'
          }
       
          },       
       
            // data傳進了new Vue里面。內部拿到了data'中的對象,嗯,就拿這個名字命名為obj把,        
             var obj={           
              message:'哈哈',     
                name:'why'          };
      // 然后通過遍歷obj這個對象拿到這個屬性------
            // Object.keys(obj)返回的是一個數組形式的這個對象的屬性
      // key代表的是每個屬性 Object.keys(obj).forEach(key => { // 拿到這個屬性 let value=obj[key] Object.defineProperty(obj,key,{
              // 設置屬性 set(newValue) {
      // 可以在這個位置監聽key的改變 value=newValue
        
              // dep.notify() 然后在類似這個地方通知訂閱者發生改變
                <!--  發生改變的時候,需要獲取到誰在用這個值,假如這里有倆個人在用張三和李四,此時就需要對每個用到message進行解析,
                根據解析html代碼,來獲取到哪些人在用這些屬性,他在獲取message里的

                值的時候,他會調用一下get方法,誰用這個message,誰都會調取一次get,到時候就能知道到底是誰調用了這個message,
                一旦newValue發生改變,就會通知這三個人,然后會通知這三個人,讓這三個人把界面更新一下 get方法---自身的update方法
                這時候就需要用發布訂閱者模式來監聽,讓這三個人訂閱這個屬性的改變-->
                        console.log('監聽'+key+'改變'+':'+value)
                    },
                    get() {
                  在類似這個的地方創建一個watch的對象。來獲取每個訂閱者
                  // const wat1=new Watcher('涵涵');
                  
      console.log('獲取'+key+'對應的值')
                  return value
                    }
                  })
                })
              // 他就會執行對象里的set屬性,把他的名字設置成'hanhan'
              obj.name='hanhan'

      我們把多個訂閱者對象添加到發布者里面,一旦值發生改變,發布者只要去調用了自己的notify,就會立馬通知之前所有的訂閱者,

      訂閱者是一個數組,遍歷數組里的每個成員,數組里面每個成員都有watch,通知訂閱者去更新自己的update。然后進行更新界面

                // 發布者
                class Dep {
                    constructor() {
                      // 訂閱了一個數組,用這個數組去記錄所有的訂閱者
                      this.subscription=[]
                    }
                    // 加入訂閱者,加進去這個人,也就是張三李四,這兩個人
                    addSub(watch) {
                      this.subscription.push(watch)
                    };
                    notify() {
                      this.subscription.forEach(item=>{
                        // 調用它自己的unpate去更新
                        item.update()
                      })
                    }
                }
      
                // 觀察者,用于監聽觀察,通過這個類創建對象,
                // 訂閱者
                class Watcher {
                  constructor(name) {
                    this.name=name;
                  }
      
                  update() {
                    // 把自己的內容進行更新
                    console.log(this.name+'發生update')
                  }
                }
      
                // 實例一個dep對象
                const dep=new Dep();
      
                const wat1=new Watcher('張三');
                dep.addSub(wat1)  //張三就被訂閱者放到了subscription的數組里面
      
                const wat2=new Watcher('李四');
                dep.addSub(wat1)  //李四就被訂閱者放到了subscription的數組里面
      
                dep.notify()//這里定義notify,那么剛才的兩個訂閱者,就全被我通知到了
              }
              
      
      

       

      下面我用一張圖對上面的內容進行一個總結吧,總結的比較膚淺,都是表面的知識,希望大家多多指點,一塊進步哈。

       

       

       

       

      observer主要是對data對象中的數據進行了劫持監聽,利用Object.defineProperty,一個屬性對應一個dep對象,name有一個dep對象,age有一個dep對象,

      他們是一一對應的關系,每個dep對象里面都 有他的觀察者對象,觀察者1,觀察者2...當屬性值發生變化的時候就會去調用dep中的notify,通知watcher,利用watcher去更新視圖。

      當el傳進complie里面時,主要是做了兩件事

      一是解析html,創建對應的watcher,放到對應的observer中的dep對象中去,具體怎么放得,上面有說哈,

      二是他還會根據el中的內容初始化view,也就是解析咱們的{{message}},在界面中顯示出  “嘻嘻”。

      假如我們把name中的屬性值改成了 '哈哈 ',那么observer中的Object.defineProperty立馬會監聽到值的改變,調用notify的方法,遍歷watcher,進行update,然后更新視圖,把 why 變為 “哈哈”

       

      分享就到這里了哈,樓樓有說的不好的地方,希望大家多多指點哈~~

       

       

      posted on 2019-11-08 14:44  牛扎糖女孩  閱讀(522)  評論(1)    收藏  舉報

      主站蜘蛛池模板: 四虎在线播放亚洲成人| 亚洲v欧美v日韩v国产v| 久久97超碰色中文字幕| 国产一区二区三区四区色| 国产精品一区二区三区黄| 视频一区视频二区卡通动漫| 日本道播放一区二区三区| 国产片AV国语在线观看手机版| 欧洲美熟女乱又伦免费视频| 国产成人8X人网站视频| 国产精品自拍中文字幕| 思思热在线视频精品| 狂躁女人双腿流白色液体| 人人妻人人狠人人爽天天综合网 | 青青草成人免费自拍视频| 极品美女自拍偷精品视频| 67194亚洲无码| 亚洲精品一区二区妖精| 国产精品高清一区二区三区| 综合激情亚洲丁香社区| 梁平县| 男人的天堂va在线无码| 国产乱色熟女一二三四区| 欧美日韩精品一区二区三区高清视频 | 无码国产欧美一区二区三区不卡 | 产综合无码一区| 缙云县| 亚洲综合无码久久精品综合| 97久久久精品综合88久久| 国产成人午夜福利精品| 亚洲人妻av伦理| 忘忧草www日本韩国| 聂拉木县| 一区二区三区国产亚洲网站| 亚洲日韩久热中文字幕| 久久av无码精品人妻系列试探| 国产婷婷综合在线视频中文| 国产精品久久久天天影视香蕉| 狠狠做五月深爱婷婷天天综合 | 深夜av在线免费观看| 日本乱子人伦在线视频|