最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解vue的數(shù)據(jù)劫持以及操作數(shù)組的坑

 更新時(shí)間:2019年04月18日 14:57:47   作者:顏醬  
這篇文章主要介紹了vue的數(shù)據(jù)劫持以及操作數(shù)組的坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

TL;DR

給data添加新屬性的時(shí)候vm.$set(vm.info,'newKey','newValue')
data上面屬性值是數(shù)組的時(shí)候,需要用數(shù)組的方法操作數(shù)組,而不能通過(guò)index或者length屬性去操作數(shù)組,因?yàn)楸O(jiān)聽(tīng)不到屬性操作的動(dòng)作。

安裝和初使用vue

vue是構(gòu)建用戶界面的漸進(jìn)式框架。所謂的漸進(jìn)式:vue + components + vue-router + vuex + vue-cli可以根據(jù)需要選擇相應(yīng)的功能。
來(lái)串命令mkdir vue-apply;cd vue-apply;npm init -y;npm i vue。
來(lái)一個(gè)html文件如下,瀏覽器瞄下~,瀏覽器控制臺(tái)vm.msg=0再看下

 <div id="app">{{msg}}</div>
  <script src="node_modules/vue/dist/vue.js"></script>
  <script>
  let vm = new Vue({
    el:'#app',
    // template加上之后會(huì)替換掉#app這個(gè)標(biāo)簽
    // template:'<h1>en</h1>',
    data:{msg:'msg'}
  })
  vm.msg = 'msg'
  </script>

說(shuō)說(shuō)mvvm mvc

mvc其實(shí)是model view Model傳統(tǒng)所有邏輯在controller,難以維護(hù)。用戶輸入 => 控制器 => 數(shù)據(jù)改變,如果數(shù)據(jù)變了需要獲取dom,操作屬性,再渲染到視圖上。

mvvm其實(shí)是model view viewModel數(shù)據(jù)變化驅(qū)動(dòng)視圖。數(shù)據(jù)變了,不需要你獲取dom,然后改變dom的內(nèi)容。這邊數(shù)據(jù)變了,vm負(fù)責(zé)監(jiān)聽(tīng),視圖那邊自動(dòng)發(fā)生變化。最明顯的是不需要document.querySelector之類的了。

vm的實(shí)質(zhì)

上面說(shuō)了vm負(fù)責(zé)讓數(shù)據(jù)變了,視圖能自動(dòng)發(fā)生變化。這么神奇魔術(shù)背后的原理是Object.defineProperty。其實(shí)就是屬性的讀取和設(shè)置操作都進(jìn)行了監(jiān)聽(tīng),當(dāng)有這樣的操作的時(shí)候,進(jìn)行某種動(dòng)作。來(lái)一個(gè)demo玩下。

// 對(duì)obj上面的屬性進(jìn)行讀取和設(shè)置監(jiān)聽(tīng)
let obj = {
    name:'huahua',
    age:18
  }
  function observer(obj){
    if(typeof obj === 'object'){
      for (const key in obj) {
        defineReactive(obj,key,obj[key])
      }
    }
  }
  // get的return的值才是最終你讀取到的值。所以設(shè)的值是為讀取準(zhǔn)備的。
  // set傳的參數(shù)是設(shè)置的值,注意這里不要有obj.name = newVal 這樣又觸發(fā)set監(jiān)聽(tīng),會(huì)死循環(huán)的。
  function defineReactive(obj,key,value){
    Object.defineProperty(obj,key,{
      get:function(){
        console.log('你在讀取')
        // happy的話這邊可以value++,這樣你發(fā)現(xiàn)讀取的值始終比設(shè)置的大一個(gè),因?yàn)閞eturn就是讀取到的值
        return value
      },
      set:function(newVal){
        console.log('數(shù)據(jù)更新了')
        value = newVal
      }

    })
  }
  observer(obj)
  obj.age = 2
  console.log(obj.age)


在瀏覽器執(zhí)行的時(shí)候,控制臺(tái)隨手也可以obj.name="hua1"類似的操作,發(fā)現(xiàn)都監(jiān)聽(tīng)到了。但是如果更深一步,obj.name={firstname:'hua',lastname:'piaoliang'};obj.name.lastname='o'就不能監(jiān)聽(tīng)到屬性修改了。因?yàn)椴](méi)有將新的賦值對(duì)象監(jiān)聽(tīng)其屬性。所以函數(shù)需要改進(jìn)。

需要在defineReactive的第一行加上observer(value)。設(shè)置值的時(shí)候如果是對(duì)象的話,也需要將這個(gè)對(duì)象數(shù)據(jù)劫持。同理,set那邊也需要加這行。

 function defineReactive(obj,key,value){
    // 注意這里?。。。。。。?
    observer(value)
    Object.defineProperty(obj,key,{
      get:function(){
        return value
      },
      set:function(newVal){
        // 注意這里?。。。。。?!
        observer(newVal)
        console.log('數(shù)據(jù)更新了')
        value = newVal
      }

    })
  }


繼續(xù),如果obj.name=[1,2,3];obj.name.push(4)發(fā)現(xiàn)又沒(méi)有通知了,這是因?yàn)镺bject.defineProperty不支持監(jiān)聽(tīng)數(shù)組變化。所以需要重寫數(shù)組上面的方法。話說(shuō),最近看了個(gè)文章,理論上也可以監(jiān)聽(tīng)數(shù)組,但是性能消耗和收益不成正比,所以,vue就沒(méi)去實(shí)現(xiàn)了。

// 把數(shù)組上大部分方法重寫了,這里不一一列舉。但是如果你 [1,2].length--,這是捕捉不到的
  let arr = ['push','slice','split']
  arr.forEach(method=>{
    let oldPush = Array.property[method]
    Array.property[method] = function(value){
      console.log('數(shù)據(jù)更新')
      oldPush.call(this,value)
    }
  })

vue使用的時(shí)候注意的坑

正如上面的解釋,vue2.0的底層約莫是這個(gè)邏輯,所以使用需要注意的點(diǎn):

因?yàn)槭且婚_(kāi)始就數(shù)據(jù)劫持了。所以后來(lái)如果新綁定屬性,是沒(méi)有數(shù)據(jù)劫持的。如果需要調(diào)用 vm.$set(vm.info,'newKey','newValue'),vm是vue的實(shí)例。

當(dāng)屬性值是數(shù)組,數(shù)組變化的時(shí)候,跟蹤不到變化。因?yàn)閿?shù)組雖然是對(duì)象,但是Object.defineProperty不支持?jǐn)?shù)組,所以vue改寫了數(shù)組的所有方法,當(dāng)調(diào)用數(shù)組方法的時(shí)候,就調(diào)動(dòng)變動(dòng)事件。但是不能通過(guò)屬性或者索引控制數(shù)組,比如length,index。

總結(jié):data上,綁定所有屬性避免后期加新屬性。如果是數(shù)組,只能通過(guò)數(shù)組方法修改數(shù)組。如下例子,控制臺(tái)vm.arr--發(fā)現(xiàn)視圖并不會(huì)變化,vm.arr.push(4)就能變化

 <div id="app">{{msg}}{{arr}}</div>
  <script src="node_modules/vue/dist/vue.js"></script>
  <script>
  let vm = new Vue({
    el:'#app',
    // template加上之后會(huì)替換掉#app這個(gè)標(biāo)簽
    // template:'<h1>en</h1>',
    data:{msg:'msg',arr:[1,2,3]}
  })
  vm.msg = 'msg'
  </script>

以上所述是小編給大家介紹的vue的數(shù)據(jù)劫持以及操作數(shù)組的坑詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評(píng)論

新密市| 高台县| 木兰县| 盐池县| 腾冲县| 镇宁| 霸州市| 临猗县| 台东县| 邯郸县| 左权县| 丽江市| 登封市| 岢岚县| 黄陵县| 阿坝县| 东平县| 北辰区| 益阳市| 珲春市| 彩票| 右玉县| 泾源县| 云霄县| 酒泉市| 宝山区| 屏山县| 三河市| 太康县| 军事| 古田县| 蒙自县| 峡江县| 北川| 五常市| 汶上县| 临潭县| 尤溪县| 楚雄市| 达日县| 新乐市|