最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當(dāng)前位置: 首頁 - 科技 - 知識(shí)百科 - 正文

怎樣做出Vue數(shù)組變異功能

來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 19:43:23
文檔

怎樣做出Vue數(shù)組變異功能

怎樣做出Vue數(shù)組變異功能:這次給大家?guī)碓鯓幼龀鯲ue數(shù)組變異功能,做出Vue數(shù)組變異功能的注意事項(xiàng)有哪些,下面就是實(shí)戰(zhàn)案例,一起來看一下。前言很多初使用Vue的同學(xué)會(huì)發(fā)現(xiàn),在改變數(shù)組的值的時(shí)候,值確實(shí)是改變了,但是視圖卻無動(dòng)于衷,果然是因?yàn)閿?shù)組太高冷了嗎?查看官方文檔才發(fā)
推薦度:
導(dǎo)讀怎樣做出Vue數(shù)組變異功能:這次給大家?guī)碓鯓幼龀鯲ue數(shù)組變異功能,做出Vue數(shù)組變異功能的注意事項(xiàng)有哪些,下面就是實(shí)戰(zhàn)案例,一起來看一下。前言很多初使用Vue的同學(xué)會(huì)發(fā)現(xiàn),在改變數(shù)組的值的時(shí)候,值確實(shí)是改變了,但是視圖卻無動(dòng)于衷,果然是因?yàn)閿?shù)組太高冷了嗎?查看官方文檔才發(fā)
這次給大家?guī)碓鯓幼龀鯲ue數(shù)組變異功能,做出Vue數(shù)組變異功能的注意事項(xiàng)有哪些,下面就是實(shí)戰(zhàn)案例,一起來看一下。

前言

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

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

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

前排提示,Vue的響應(yīng)式原理主要是使用了ES5的Object.defineProperty,毫不知情的同學(xué)可以查看相關(guān)資料。

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

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

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() {
}

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

咦,一切居然都如預(yù)想猜想的一樣。

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

雖然你想象中的女神可能會(huì)這種姿勢(shì),但是你眼前的這個(gè)女神確實(shí)不是這種姿勢(shì)的,像我這種屌絲屬性暴露無疑的人怎么可能猜透女神的心思?為什么不這樣響應(yīng)數(shù)據(jù)呢?或許是因?yàn)閿?shù)組和對(duì)象還是有所差別,定義數(shù)組的屬性可能會(huì)產(chǎn)生一些麻煩與Bug。又或許是因?yàn)樵诮换サ倪^程中可能會(huì)產(chǎn)生大量的數(shù)據(jù),導(dǎo)致整體的性能下降。也有可能是作者權(quán)衡利弊之后用其他方法也可以達(dá)到數(shù)據(jù)響應(yīng)的效果。反正我是猜不透啦。

為啥調(diào)用數(shù)組原生方法就可以響應(yīng)了?

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

簡(jiǎn)單的來講,def的作用就是重新定義對(duì)象屬性的value值。

//array.js
import { def } from '../util/index'
const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)
//arrayMethods是對(duì)數(shù)組的原型對(duì)象的拷貝,
//在之后會(huì)將該對(duì)象里的特定方法進(jìn)行變異后替換正常的數(shù)組原型對(duì)象
/**
 * 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是對(duì)數(shù)組的一些方法進(jìn)行變異,我們以push方法來舉個(gè)例子。首先 就是要用original = arrayProto['push']來保存原生的push方法。

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

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

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);

在控制臺(tái)中查看結(jié)果為:。

那么源碼中的

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()

這段代碼就是對(duì)應(yīng)的doSomething()了

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

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

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

相信看了本文案例你已經(jīng)掌握了方法,更多精彩請(qǐng)關(guān)注Gxl網(wǎng)其它相關(guān)文章!

推薦閱讀:

怎樣使用Vue實(shí)現(xiàn)樹形視圖數(shù)據(jù)

JS對(duì)DOM樹實(shí)現(xiàn)遍歷有哪些方法

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

怎樣做出Vue數(shù)組變異功能

怎樣做出Vue數(shù)組變異功能:這次給大家?guī)碓鯓幼龀鯲ue數(shù)組變異功能,做出Vue數(shù)組變異功能的注意事項(xiàng)有哪些,下面就是實(shí)戰(zhàn)案例,一起來看一下。前言很多初使用Vue的同學(xué)會(huì)發(fā)現(xiàn),在改變數(shù)組的值的時(shí)候,值確實(shí)是改變了,但是視圖卻無動(dòng)于衷,果然是因?yàn)閿?shù)組太高冷了嗎?查看官方文檔才發(fā)
推薦度:
標(biāo)簽: VUE 變異 數(shù)組
  • 熱門焦點(diǎn)

最新推薦

猜你喜歡

熱門推薦

專題
Top