日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Vue中避免濫用this去讀取data中數(shù)據(jù)

瀏覽:20日期:2022-10-04 13:47:59
前言

在Vue中,data選項(xiàng)是個(gè)好東西,把數(shù)據(jù)往里一丟,在一個(gè)Vue組件中任何一個(gè)地方都可以通過(guò)this來(lái)讀取data中數(shù)據(jù)。但是要避免濫用this去讀取data中數(shù)據(jù),至于在哪里要避免濫用,如果濫用會(huì)導(dǎo)致什么后果,本專欄將會(huì)一一揭曉。

一、用this讀取data中數(shù)據(jù)的過(guò)程

在Vue源碼中會(huì)把data中數(shù)據(jù)添加getter函數(shù)和setter函數(shù),將其轉(zhuǎn)成響應(yīng)式的。getter函數(shù)代碼如下所示:

function reactiveGetter() { var value = getter ? getter.call(obj) : val; if (Dep.target) { dep.depend(); if (childOb) { childOb.dep.depend(); if (Array.isArray(value)) { dependArray(value); } } } return value}

用this讀取data中數(shù)據(jù)時(shí),會(huì)觸發(fā)getter函數(shù),在其中通過(guò) var value = getter ? getter.call(obj) : val; 獲取到值后執(zhí)行 return value,實(shí)現(xiàn)讀取數(shù)據(jù)的目的。

這里可以得出一個(gè)結(jié)論,在Dep.target存在時(shí),使用this去讀取data中數(shù)據(jù)時(shí)會(huì)去收集依賴。如果濫用this去讀取data中數(shù)據(jù),會(huì)多次重復(fù)地收集依賴,從而產(chǎn)生性能問(wèn)題。

二、Dep.target什么時(shí)候存在

Dep.target是由依賴賦值的。依賴又稱為Watcher(偵聽(tīng)者)或者訂閱者。在Vue中有三種依賴,其中兩種是很常見(jiàn)的,就是watch(偵聽(tīng)器)和computed(計(jì)算屬性)。還有一種隱藏的依賴———渲染W(wǎng)atcher,在模板首次渲染的過(guò)程中創(chuàng)建的。

Dep.target是在依賴創(chuàng)建時(shí)被賦值,依賴是用構(gòu)造函數(shù)Watcher創(chuàng)建。

function Watcher(vm, expOrFn, cb, options, isRenderWatcher) { //... if (typeof expOrFn === ’function’) { this.getter = expOrFn; } else { this.getter = parsePath(expOrFn); } this.value = this.lazy ? undefined : this.get();};Watcher.prototype.get = function get() { pushTarget(this); try { value = this.getter.call(vm, vm); } catch (e) { } return value};Dep.target = null;var targetStack = [];function pushTarget(target) { targetStack.push(target); Dep.target = target;}

在構(gòu)造函數(shù)Watcher最后會(huì)執(zhí)行實(shí)例方法get,在實(shí)例方法get中執(zhí)行pushTarget(this)中給Dep.target賦值的。

而依賴是在Vue頁(yè)面或組件初次渲染時(shí)創(chuàng)建,所以產(chǎn)生的性能問(wèn)題應(yīng)該是首次渲染過(guò)慢的問(wèn)題。

三、在何處濫用this去讀取data中數(shù)據(jù)

在Dep.target存在時(shí)去執(zhí)行這些濫用this去讀取data中數(shù)據(jù)的代碼會(huì)產(chǎn)生性能問(wèn)題,故還要搞清楚這些代碼是寫在哪里才會(huì)被執(zhí)行到,換句話來(lái)說(shuō),要搞清楚在哪里濫用this去讀取data中數(shù)據(jù)會(huì)產(chǎn)生性能問(wèn)題。

在第二小節(jié)中介紹了Dep.target被賦值后會(huì)執(zhí)行value = this.getter.call(vm, vm),其中this.getter是一個(gè)函數(shù),那么若在其中有用this去讀取data數(shù)據(jù),就會(huì)去收集依賴,假如濫用的話就會(huì)產(chǎn)生性能問(wèn)題。

this.getter是在創(chuàng)建依賴過(guò)程中賦值的,每種依賴的this.getter都是不相同的。下面來(lái)一一介紹。

watch(偵聽(tīng)器)依賴的this.getter是parsePath函數(shù),其函數(shù)參數(shù)就是偵聽(tīng)的對(duì)象。

var bailRE = new RegExp(('[^' + (unicodeRegExp.source) + '.$_d]'));function parsePath(path) { if (bailRE.test(path)) { return } var segments = path.split(’.’); return function(obj) { for (var i = 0; i < segments.length; i++) { if (!obj) { return } obj = obj[segments[i]]; } return obj }}

如下所示的代碼中的 a 和 a.b.c作為參數(shù)傳入parsePath函數(shù)會(huì)返回一個(gè)函數(shù)賦值給this.getter,執(zhí)行this.getter.call(vm, vm)會(huì)得到this.a和this.a.b.c的值。在這個(gè)過(guò)程中不會(huì)存在濫用this去讀取data中數(shù)據(jù)的場(chǎng)景。

watch:{ a:function(newVal, oldVal){ //做點(diǎn)什么 }}vm.$watch(’a.b.c’, function (newVal, oldVal) { // 做點(diǎn)什么}) computed(計(jì)算屬性)依賴的this.getter有兩種,如果計(jì)算屬性的值是個(gè)函數(shù),那么this.getter就是這個(gè)函數(shù)。如果計(jì)算屬性的值是個(gè)對(duì)象,那么this.getter就是這個(gè)對(duì)象的get屬性值,get屬性值也是個(gè)函數(shù)。在這個(gè)函數(shù)可能會(huì)存在濫用this去讀取data中數(shù)據(jù)的場(chǎng)景,舉個(gè)例子,代碼如下所示。

computed:{ d:function(){ let result = 0; for(let key in this.a){ if(this.a[key].num > 20){ result += this.a[key].num + this.b + this.c; }else{ result += this.a[key].num + this.e + this.f; } } return result; }}

在計(jì)算屬性d中就存在濫用this去讀取data數(shù)據(jù)。其中this.a是個(gè)數(shù)組,此時(shí)Dep.target的值為計(jì)算屬性d這個(gè)依賴,在循環(huán)this.a中使用this去獲取中a、b、c、e、f的數(shù)據(jù),使這些數(shù)據(jù)進(jìn)行一系列復(fù)雜的邏輯運(yùn)算來(lái)重復(fù)地收集計(jì)算屬性d這個(gè)依賴。導(dǎo)致獲取計(jì)算屬性d的值的速度變慢,從而產(chǎn)生性能問(wèn)題。

渲染W(wǎng)atcher的this.getter是一個(gè)函數(shù)如下所示:

updateComponent = function() { vm._update(vm._render(), hydrating);};

其中vm._render()會(huì)把template模板生成的渲染函數(shù)render轉(zhuǎn)成虛擬DOM(VNode):vnode = render.call(vm._renderProxy, vm.$createElement);,舉一個(gè)例子來(lái)說(shuō)明一下渲染函數(shù)render是什么。

例如template模板:

<template> <div class='wrap'> <p>{{a}}<span>{{b}}</span></p> </div></template>

通過(guò)vue-loader會(huì)生成渲染函數(shù)render,如下所示:

(function anonymous() { with(this) { return _c(’div’, { attrs: { 'class': 'wrap' } }, [_c(’p’, [_v(_s(a)), _c(’span’, [_v(_s(b))])])]) }})

其中with語(yǔ)句的作用是為一個(gè)或一組語(yǔ)句指定默認(rèn)對(duì)象,例with(this){ a + b } 等同 this.a + this.b,那么在template模板中使用{{ a }}相當(dāng)使用this去讀取data中的a數(shù)據(jù)。故在template模板生成的渲染函數(shù)render中也可能存在濫用this去讀取data中數(shù)據(jù)的場(chǎng)景。舉個(gè)例子,代碼如下所示:

<template> <div class='wrap'> <div v-for=item in list> <div> {{ arr[item.index][’name’] }} </div> <div> {{ obj[item.id][’age’] }} </div> </div> </div></template>

其中用v-for循環(huán)list數(shù)組過(guò)程中,不斷用this去讀取data中arr、obj的數(shù)據(jù),使這些數(shù)據(jù)進(jìn)行一系列復(fù)雜的邏輯運(yùn)算來(lái)重復(fù)收集這個(gè)依賴,導(dǎo)致初次渲染的速度變慢,從而產(chǎn)生性能問(wèn)題。

四、如何避免濫用this去讀取data中數(shù)據(jù)

綜上所述在計(jì)算屬性和template模板中濫用this去讀取data中數(shù)據(jù)會(huì)導(dǎo)致多次重復(fù)地收集依賴,從而產(chǎn)生性能問(wèn)題,那要怎么避免這種情況。

計(jì)算屬性中如何避免

用ES6對(duì)象解構(gòu)賦值來(lái)避免,計(jì)算屬性的值是一個(gè)函數(shù),其參數(shù)是Vue的實(shí)例化this對(duì)象,在上述計(jì)算屬性中濫用this的例子中可以這樣優(yōu)化。

優(yōu)化前:

computed:{ d:function(){ let result = 0; for(let key in this.a){ if(this.a[key].num > 20){ result += this.a[key].num + this.b + this.c; }else{ result += this.a[key].num + this.e + this.f; } } return result; }}

優(yōu)化后:

computed: { d({ a, b, c, e, f }) { let result = 0; for (let key in a) { if (a[key].num > 20) { result += a[key].num + b + c; } else { result += a[key].num + e + f; } } return result; }}

以上利用解構(gòu)賦值提前把data數(shù)據(jù)中的a、b、c、e、f賦值給對(duì)應(yīng)的變量a、b、c、e、f,然后在計(jì)算屬性中可以通過(guò)這些變量訪問(wèn)data數(shù)據(jù)的,且不會(huì)觸發(fā)data中對(duì)應(yīng)數(shù)據(jù)的依賴收集。這樣只用this讀取了一次data中的數(shù)據(jù),只觸發(fā)了一次依賴收集,避免了多次重復(fù)地依賴收集產(chǎn)生的性能問(wèn)題。

template模板中如何避免

提前處理v-for循環(huán)所用的數(shù)據(jù),不要在v-for循環(huán)中去讀取數(shù)組、對(duì)象類型的數(shù)據(jù)。在上述template模板中濫用this的例子中可以這樣優(yōu)化。

假設(shè)list、arr、obj皆是服務(wù)端返回來(lái)的數(shù)據(jù),且arr和obj沒(méi)有用到任何模塊渲染中,可以這樣優(yōu)化。

優(yōu)化前:

<template> <div class='wrap'> <div v-for=item in list> <div> {{ arr[item.index][’name’] }} </div> <div> {{ obj[item.id][’age’] }} </div> </div> </div></template>

優(yōu)化后:

<template> <div class='wrap'> <div v-for=item in listData> <div{{item.name}} </div> <div>{{item.age}}</div> </div> </div></template><script>const arr = [];const obj = {}export default { data() { return { list: [], } }, computed: { listData: function ({list}) { list.forEach(item => { item.name = arr[item.index].name; item.age = obj[item.id].age; }) return list; } },}</script>

以上就是Vue中避免濫用this去讀取data中數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于Vue中避免濫用this的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Vue
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日本а中文在线天堂| 日韩精品免费一区二区夜夜嗨| 欧美一区不卡| 欧美日韩一区二区三区不卡视频| 日韩精品一区二区三区中文字幕| 午夜久久av| 国产精品欧美三级在线观看 | 国产精品久久久久9999高清| 国产精品亚洲一区二区在线观看| 精品五月天堂| 久久久国产精品一区二区中文| 国模 一区 二区 三区| 亚洲一区日韩| 日韩不卡一区二区| 97精品视频在线看| 欧美日韩四区| 91嫩草精品| 日本久久精品| 国产亚洲毛片| 日韩中文字幕1| 久久一区精品| 99热国内精品| 亚洲精品韩国| 91视频精品| 视频一区二区欧美| 国产精品白丝av嫩草影院| 国产成人精品亚洲日本在线观看| 亚洲深夜福利| 欧美国产极品| 欧美日韩色图| 国产精品最新自拍| 久久一区二区三区喷水| 最新国产精品久久久| 精品久久久亚洲| 亚洲网站视频| 国产黄色一区| 久久亚洲视频| 成人综合一区| 国产精品超碰| 久久精品一区二区国产| 在线成人直播| 国产美女视频一区二区| 欧美日韩在线二区| 国产乱论精品| 伊人久久婷婷| 美女视频黄久久| 久热精品在线| 久久蜜桃资源一区二区老牛| 日韩高清二区| 日韩成人高清| 你懂的网址国产 欧美| 午夜在线观看免费一区| 麻豆理论在线观看| 国产日产一区| 蜜桃久久久久久| 成人久久久久| 久久精品国产免费| 亚洲精品乱码久久久久久蜜桃麻豆| 久久天堂av| 国产一区丝袜| 国产欧美啪啪| 日韩精品一区二区三区av| 女人av一区| 国产夫妻在线| 欧美精品第一区| 午夜久久av | 国产一区二区视频在线看| 国产精品日韩| 欧美日韩激情| 久久精品卡一| 日韩在线短视频| 国产精品99精品一区二区三区∴ | 久久xxxx精品视频| 在线看片日韩| 91视频久久| 欧美国产先锋| 国产精品红桃| 91精品日本| 日韩欧美久久| 视频一区二区中文字幕| 国产精品嫩草99av在线| 婷婷综合六月| 亚洲va中文在线播放免费| 国产h片在线观看| 国产精品视频一区二区三区| 人人爽香蕉精品| 亚洲精品进入| 欧美日韩调教| 青青在线精品| 国产亚洲欧美日韩在线观看一区二区| 亚洲一区二区三区四区五区午夜| 亚洲女同一区| 蜜桃伊人久久| 日本vs亚洲vs韩国一区三区二区| 亚洲一区二区小说| 日韩欧美高清一区二区三区| 亚洲精品观看| 久久国内精品自在自线400部| 欧美亚洲福利| 精品视频91| 久久亚洲黄色| 日韩国产欧美| 欧美+亚洲+精品+三区| 亚洲成人三区| 综合激情婷婷| 国产毛片久久久| 精品久久在线| 久久久久欧美精品| 欧美日韩视频| 日韩精品亚洲专区在线观看| 国产日韩高清一区二区三区在线| 国产精品啊v在线| 91亚洲成人| 欧美+亚洲+精品+三区| 欧美午夜不卡影院在线观看完整版免费| 日韩在线综合| 欧美日韩国产亚洲一区| 亚洲人成网站在线在线观看| 欧美视频精品全部免费观看| 久久一区视频| 国产在线欧美| 婷婷视频一区二区三区| 国产精品久久亚洲不卡| 日韩国产专区| 亚洲一区欧美二区| 97成人超碰| 欧美激情另类| 好看的亚洲午夜视频在线| 在线精品福利| 精品伊人久久久| 久久要要av| 97se亚洲| 欧美aa在线观看| 亚洲深深色噜噜狠狠爱网站 | 男女精品网站| 国产精品亚洲综合在线观看| 欧美日韩精品免费观看视完整| 鲁大师影院一区二区三区| 91成人小视频| 国产精品成人a在线观看| 午夜久久美女| 麻豆久久一区| 宅男噜噜噜66国产日韩在线观看| 欧美亚洲自偷自偷| 日韩一区二区中文| 亚洲3区在线| 成人免费网站www网站高清| 午夜性色一区二区三区免费视频| 国产精品久久久久蜜臀| 深夜福利亚洲| 婷婷激情一区| 国产精品一级| 国产亚洲一级| 国产精品99久久精品| 噜噜噜久久亚洲精品国产品小说| 日本精品黄色| 欧美色综合网| 蜜臀久久99精品久久久画质超高清 | 国产拍在线视频| 日本亚洲最大的色成网站www| 日韩电影在线视频| 欧美精品中文字幕亚洲专区| 日韩视频精品在线观看| 久久久国产精品入口麻豆| 国精品一区二区| 精品入口麻豆88视频| 亚洲v天堂v手机在线| 国产真实久久| 精品一区二区三区免费看| 亚洲精品综合| 亚洲高清久久| 国产a亚洲精品| 久久精品99国产国产精| 美女黄网久久| 中文字幕系列一区| 麻豆视频一区| 日韩欧乱色一区二区三区在线| 蜜桃国内精品久久久久软件9| 国内精品美女在线观看| 日韩1区2区日韩1区2区| 亚洲乱码视频| 午夜一区在线| 久久久久国产| 国产传媒在线观看| 麻豆国产精品| 国产精品最新| 国产亚洲久久| 亚洲精品在线二区| 亚洲免费播放| 亚洲性图久久| 99久久夜色精品国产亚洲狼| 麻豆精品蜜桃视频网站| 国产私拍福利精品视频二区| 日韩手机在线| 免费日韩精品中文字幕视频在线| 在线视频观看日韩| 久久九九精品| 激情久久中文字幕| 欧美成人综合| 在线成人直播|