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

淺談Vue響應式(數(shù)組變異方法)

 更新時間:2018年05月07日 09:19:58   作者:王興欣  
這篇文章主要介紹了淺談Vue響應式(數(shù)組變異方法),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

前言

很多初使用Vue的同學會發(fā)現(xiàn),在改變數(shù)組的值的時候,值確實是改變了,但是視圖卻無動于衷,果然是因為數(shù)組太高冷了嗎?

查看官方文檔才發(fā)現(xiàn),不是女神太高冷,而是你沒用對方法。

看來想讓女神自己動,關鍵得用對方法。雖然在官方文檔中已經給出了方法,但是在下實在好奇的緊,想要解鎖更多姿勢的話,那就必須先要深入女神的心,于是乎才有了去探索Vue響應式原理的想法。(如果你愿意一層一層地剝開我的心。你會發(fā)現(xiàn),你會訝異…… 沉迷于鬼哭狼嚎 無法自拔QAQ)。

前排提示,Vue的響應式原理主要是使用了ES5的Object.defineProperty,毫不知情的同學可以查看相關資料。

為啥數(shù)組不響應?

仔細一想,Vue的響應是基于Object.definePropery的,這個方法主要是對對象屬性的描述進行修改。數(shù)組其實也是對象,通過定義數(shù)組的屬性應該也能產生響應的效果呀。先驗證一下自己的想法,擼起袖子就開干。

const arr = [1,2,3];

let val = arr[0];

Object.defineProperty(arr,'0',{
  enumerable: true,
  configurable: true,
  get(){
    doSomething();
    return val;
  },
  set(a){
    val = a;
    doSomething();
  }
});

function doSomething() {

}

然后在控制臺中分別輸入arr、arr[0] = 2、arr,可以看到如下圖的結果。

咦,一切居然都如預想猜想的一樣。

接下來,看到這段代碼,有的同學可能會有所疑問,為啥在get()方法里不直接返回this[0]呢?而是要借助val來返回值呢?仔細一想,臥槽?。?!差點特么的死循環(huán)了,你想呀,get()本身就是獲取當前屬性的值,在get()里調用this[0]不是等同于再次調用了get()方法嗎? 好可怕好可怕,簡直嚇死勞資了。

雖然你想象中的女神可能會這種姿勢,但是你眼前的這個女神確實不是這種姿勢的,像我這種屌絲屬性暴露無疑的人怎么可能猜透女神的心思?為什么不這樣響應數(shù)據(jù)呢?或許是因為數(shù)組和對象還是有所差別,定義數(shù)組的屬性可能會產生一些麻煩與Bug。又或許是因為在交互的過程中可能會產生大量的數(shù)據(jù),導致整體的性能下降。也有可能是作者權衡利弊之后用其他方法也可以達到數(shù)據(jù)響應的效果。反正我是猜不透啦。

為啥調用數(shù)組原生方法就可以響應了?

為什么使用了這些數(shù)組的方法就就能讓數(shù)據(jù)響應了呢?先看看數(shù)組部分的源碼吧。

簡單的來講,def的作用就是重新定義對象屬性的value值。

//array.js
import { def } from '../util/index'

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)
//arrayMethods是對數(shù)組的原型對象的拷貝,
//在之后會將該對象里的特定方法進行變異后替換正常的數(shù)組原型對象
/**
 * Intercept mutating methods and emit events
 */
[
 'push',
 'pop',
 'shift',
 'unshift',
 'splice',
 'sort',
 'reverse'
]
.forEach(function (method) {
 // cache original method
 //將上面的方法保存到original中
 const original = arrayProto[method]
 def(arrayMethods, method, function mutator (...args) {
  const result = original.apply(this, args)
  const ob = this.__ob__
  let inserted
  switch (method) {
   case 'push':
   case 'unshift':
    inserted = args
    break
   case 'splice':
    inserted = args.slice(2)
    break
  }
  if (inserted) ob.observeArray(inserted)
  // notify change
  ob.dep.notify()
  return result
 })
})

貼出def部分的代碼

/**
 * Define a property.
 */
export function def (obj: Object, key: string, val: any, enumerable?: boolean) {
 Object.defineProperty(obj, key, {
  value: val,
  enumerable: !!enumerable,
  writable: true,
  configurable: true
 })
}

array.js是對數(shù)組的一些方法進行變異,我們以push方法來舉個例子。首先 就是要用original = arrayProto['push']來保存原生的push方法。

然后就是要定義變異的方法了,對于def函數(shù),如果不深究的話,def(arrayMethods,method,function(){}),這個函數(shù)可以粗略的表示為arrayMethods[method] = function mutator(){};

假設在之后調用push方法,實際上調用的是mutator方法,在mutator方法中,第一件事就是調用保存了原生push方法的original,先求出實際的值。一堆文字看起來實在很抽象,那么寫一段低配版的代碼來表達源碼的含義。

const push = Array.prototype.push;

Array.prototype.push = function mutator (...arg){
  const result = push.apply(this,arg);
  doSomething();
  return result
}

function doSomething(){
  console.log('do something');
}

const arr = [];
arr.push(1);
arr.push(2);
arr.push(3);

在控制臺中查看結果為:。

那么源碼中的

const ob = this.__ob__
  let inserted
  switch (method) {
   case 'push':
   case 'unshift':
    inserted = args
    break
   case 'splice':
    inserted = args.slice(2)
    break
  }
  if (inserted) ob.observeArray(inserted)
  // notify change
  ob.dep.notify()

這段代碼就是對應的doSomething()了

在該代碼中,清清楚楚的寫了2個單詞的注釋notify change,不認識這2個單詞的同學就百度一下嘛,這里就由我代勞了,這倆單詞的意思是發(fā)布改變!每次調用了該方法,都會求出值,然后做一些其他的事情,比如發(fā)布改變與觀察新增的元素,響應的其他過程在本篇就不討論了。

[
 'push',
 'pop',
 'shift',
 'unshift',
 'splice',
 'sort',
 'reverse'
]

目前一共有這么些方法,只要用對方法就能改變女神的姿勢喲!

小結

對于標題,我一改再改,一開始叫淺析Vue響應原理,但是后來一看 這個標題實在太大,那就從最簡單的入手吧,先從數(shù)組入手,而且本篇也不會花費太多時間去閱讀。如果本篇有什么地方寫得有誤,誤導了他人,請一定指出,萬分感激。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Vue中對<style scoped> 中的scoped屬性解析

    Vue中對<style scoped> 中的scoped屬性解析

    在Vue的單文件組件中,<style scoped> 的 scoped 屬性用于實現(xiàn)?樣式作用域隔離?,下面通過實例代碼講解Vue中對<style scoped>中的scoped屬性,感興趣的朋友一起看看吧
    2025-03-03
  • 前端vue項目如何使用Decimal.js做加減乘除求余運算

    前端vue項目如何使用Decimal.js做加減乘除求余運算

    decimal.js是使用的二進制來計算的,可以更好地實現(xiàn)格化式數(shù)學運算,對數(shù)字進行高精度處理,使用decimal類型處理數(shù)據(jù)可以保證數(shù)據(jù)計算更為精確,這篇文章主要給大家介紹了關于前端vue項目如何使用Decimal.js做加減乘除求余運算的相關資料,需要的朋友可以參考下
    2024-05-05
  • vue中map()快速使用方法小結

    vue中map()快速使用方法小結

    map()函數(shù)是在JS的數(shù)組中定義的,它返回一個新的數(shù)組,下面這篇文章主要給大家介紹了關于vue中map()快速使用的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-12-12
  • VUE 組件轉換為微信小程序組件的方法

    VUE 組件轉換為微信小程序組件的方法

    這篇文章主要介紹了VUE 組件轉換為微信小程序組件的方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • vue Element左側無限級菜單實現(xiàn)

    vue Element左側無限級菜單實現(xiàn)

    這篇文章主要介紹了vue Element左側無限級菜單實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • vue3+echarts+折線投影(陰影)效果的實現(xiàn)

    vue3+echarts+折線投影(陰影)效果的實現(xiàn)

    這篇文章主要介紹了vue3+echarts+折線投影(陰影)效果的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Vue項目在IE瀏覽器的兼容問題及解決方法

    Vue項目在IE瀏覽器的兼容問題及解決方法

    該文章主要介紹了如何在Vue項目中解決IE瀏覽器的兼容性問題,包括解決IE不兼容axios的Promise對象、ES6語法以及polyfill的使用方法,通過配置babel-polyfill、es6-promise和轉ES5語法,解決了在IE瀏覽器中常見的兼容性問題,需要的朋友可以參考下
    2025-01-01
  • flv.js在vue中的使用方法

    flv.js在vue中的使用方法

    flv.js是一個用于在瀏覽器中解碼和播放FLV視頻的JavaScript庫,它可以將FLV視頻流解碼并顯示在HTML5的video元素中,從而實現(xiàn)在瀏覽器中直接播放FLV格式的視頻文件,本文給大家介紹flv.js在vue中的使用,感興趣的朋友一起看看吧
    2023-11-11
  • Vue取消Axios發(fā)出的請求

    Vue取消Axios發(fā)出的請求

    axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。首先需要知道:axios不是一種新的技術。axios 是一個基于Promise 用于瀏覽器和 nodejs 的 HTTP 客戶端,本質上也是對原生XHR的封裝,只不過它是Promise的實現(xiàn)版本,符合最新的ES規(guī)范
    2022-09-09
  • vue 獲取元素額外生成的data-v-xxx操作

    vue 獲取元素額外生成的data-v-xxx操作

    這篇文章主要介紹了vue 獲取元素額外生成的data-v-xxx操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09

最新評論

铜鼓县| 宜城市| 长治县| 垦利县| 襄汾县| 易门县| 特克斯县| 拜城县| 崇阳县| 明光市| 瓦房店市| 谢通门县| 邛崃市| 永靖县| 达日县| 兴安盟| 云浮市| 抚顺县| 天全县| 吴江市| 文化| 阜阳市| 章丘市| 阳山县| 岑溪市| 资溪县| 和政县| 贵州省| 丽江市| 乌拉特前旗| 定襄县| 乐亭县| 旌德县| 阿鲁科尔沁旗| 五指山市| 梧州市| 平顺县| 米易县| 青浦区| 卓资县| 罗平县|