成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

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

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

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

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

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

在Vue源碼中會把data中數(shù)據(jù)添加getter函數(shù)和setter函數(shù),將其轉(zhuǎn)成響應式的。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ù)時,會觸發(fā)getter函數(shù),在其中通過 var value = getter ? getter.call(obj) : val; 獲取到值后執(zhí)行 return value,實現(xiàn)讀取數(shù)據(jù)的目的。

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

二、Dep.target什么時候存在

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

Dep.target是在依賴創(chuàng)建時被賦值,依賴是用構(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最后會執(zhí)行實例方法get,在實例方法get中執(zhí)行pushTarget(this)中給Dep.target賦值的。

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

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

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

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

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

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

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ù)會返回一個函數(shù)賦值給this.getter,執(zhí)行this.getter.call(vm, vm)會得到this.a和this.a.b.c的值。在這個過程中不會存在濫用this去讀取data中數(shù)據(jù)的場景。

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

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

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

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

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

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

例如template模板:

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

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

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

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

<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ù)組過程中,不斷用this去讀取data中arr、obj的數(shù)據(jù),使這些數(shù)據(jù)進行一系列復雜的邏輯運算來重復收集這個依賴,導致初次渲染的速度變慢,從而產(chǎn)生性能問題。

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

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

計算屬性中如何避免

用ES6對象解構(gòu)賦值來避免,計算屬性的值是一個函數(shù),其參數(shù)是Vue的實例化this對象,在上述計算屬性中濫用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賦值給對應的變量a、b、c、e、f,然后在計算屬性中可以通過這些變量訪問data數(shù)據(jù)的,且不會觸發(fā)data中對應數(shù)據(jù)的依賴收集。這樣只用this讀取了一次data中的數(shù)據(jù),只觸發(fā)了一次依賴收集,避免了多次重復地依賴收集產(chǎn)生的性能問題。

template模板中如何避免

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

假設list、arr、obj皆是服務端返回來的數(shù)據(jù),且arr和obj沒有用到任何模塊渲染中,可以這樣優(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ù)的詳細內(nèi)容,更多關(guān)于Vue中避免濫用this的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標簽: Vue
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
91精品国产综合久久小美女| 午夜一区二区三视频在线观看| 欧美人与禽猛交乱配| 久久经典综合| 亚洲激情图片qvod| 国内精品亚洲| 国产视频一区在线观看| 国产精品18久久久久| 欧美亚洲一区二区三区四区| 日本特黄久久久高潮| 欧美中文字幕| 亚洲影院在线观看| 亚洲精品欧美精品| 亚洲色图视频网站| 亚洲精品1区2区| 亚洲欧美日韩一区| 一区二区不卡在线视频 午夜欧美不卡'| 国产视频一区二区在线观看| 自拍偷拍亚洲综合| 欧美这里有精品| 日本高清视频一区二区| 91精品福利在线| 国产成人精品亚洲日本在线桃色| 一本大道久久精品懂色aⅴ| 欧美一区二区在线看| 韩日午夜在线资源一区二区| 色综合色综合色综合 | 久久都是精品| 亚洲综合色自拍一区| 亚洲码国产岛国毛片在线| 国产一区二区三区自拍| 成人av在线观| 一区二区三区久久久| 午夜免费久久看| 91免费看`日韩一区二区| 久久新电视剧免费观看| 亚洲欧美一区二区原创| 国产精品色噜噜| 亚洲视频免费| 亚洲欧美aⅴ...| 亚洲一区二区在| 天天操天天综合网| 欧美午夜精品一区二区三区| 国内精品国产成人国产三级粉色| 欧美一区二区黄| 97精品久久久午夜一区二区三区 | av激情综合网| 亚洲国产精品v| 中文有码久久| 青青草97国产精品免费观看| 制服丝袜中文字幕亚洲| 成人久久视频在线观看| 国产丝袜欧美中文另类| 亚洲精品美女| 日韩国产在线观看一区| 欧美日本韩国一区| 成人免费视频网站在线观看| 中文子幕无线码一区tr| 国产精品国产三级国产a| 国产视频一区在线观看一区免费| 天天影视网天天综合色在线播放| 欧美日韩亚洲丝袜制服| 本田岬高潮一区二区三区| 国产精品视频在线看| 中国成人在线视频| 久久综合综合久久综合| 精品国产乱码久久久久久图片| 韩日精品在线| 免费国产亚洲视频| 久久亚洲一级片| 一区二区三区|亚洲午夜| 免费在线观看精品| 亚洲精品一区二区三区香蕉| 亚洲精品乱码久久久久久蜜桃麻豆| 麻豆精品一区二区三区| 久久久国产精品麻豆| 国产精品亚洲不卡a| 国产一区欧美二区| 国产精品美女久久久久久久久 | 成人爽a毛片一区二区免费| 欧美国产日韩一二三区| 精品999久久久| 一区二区三区四区五区精品| 激情小说欧美图片| 国产精品午夜在线| 色呦呦一区二区三区| 国产伦精一区二区三区| 日本一区二区久久| 在线影视一区二区三区| www.欧美日韩国产在线| 亚洲国产精品麻豆| 欧美变态tickling挠脚心| 宅男噜噜噜66国产日韩在线观看| 国产精品99久久久久久久vr| 亚洲精品写真福利| 日韩欧美一二三| 亚洲精品系列| 国产在线视频一区二区三区| 中文字幕中文字幕一区二区| 欧美亚洲图片小说| 国内成人在线| 国产主播一区二区| 亚洲同性gay激情无套| 欧美视频三区在线播放| 黄色一区二区三区四区| 国产在线不卡一卡二卡三卡四卡| 日韩一区欧美小说| 91精品国产欧美日韩| 野花国产精品入口| 国产不卡在线视频| 亚洲成人资源网| 精品国产网站在线观看| 久久久久久九九九九| 99精品偷自拍| 麻豆精品一区二区三区| 综合精品久久久| 欧美一区二区大片| 久久激情久久| 在线观看一区视频| 不卡电影免费在线播放一区| 日韩成人av影视| 亚洲欧洲av另类| 欧美videofree性高清杂交| 老司机午夜精品视频在线观看| 欧美日韩中文| 国产福利一区二区三区视频| 亚洲最色的网站| 欧美国产日韩精品免费观看| 91精品国产高清一区二区三区蜜臀| 一本色道亚洲精品aⅴ| 影院欧美亚洲| 成人黄色小视频| 青青草国产成人av片免费| 亚洲欧美在线视频观看| 欧美mv和日韩mv国产网站| 色久综合一二码| 99re66热这里只有精品4| 99re在线精品| 国产乱码字幕精品高清av| 午夜欧美电影在线观看| 亚洲伦在线观看| www激情久久| 在线成人高清不卡| 色94色欧美sute亚洲13| 国产欧美午夜| 极品日韩av| 欧美区日韩区| 99免费精品视频| 国产九色sp调教91| 久久精品国产一区二区三| 亚洲大型综合色站| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆| 精品国产自在久精品国产| 欧美日韩综合在线| 色婷婷精品大视频在线蜜桃视频| 国产亚洲毛片在线| 欧美日一区二区在线观看| 成人免费的视频| 国产91精品精华液一区二区三区 | 懂色av噜噜一区二区三区av| 欧美一区二区网站| 成人教育av在线| 国产日韩精品久久久| 欧美福利一区| 亚洲图片欧美一区| 欧美视频在线一区二区三区| jvid福利写真一区二区三区| 中文字幕在线播放不卡一区| 国产精品三区www17con| 蜜臀av性久久久久蜜臀aⅴ| 日韩三级在线免费观看| 国产精品久久| 日本一区中文字幕| 精品久久五月天| 激情亚洲成人| 日韩电影在线免费| 欧美精品一区二区三区蜜桃| 亚洲精品一区二区三| 日本不卡视频一二三区| 精品国产露脸精彩对白| 亚洲高清视频一区| 久久超碰97人人做人人爱| 久久综合色一综合色88| 午夜视频久久久| 亚洲成人av一区二区三区| 91麻豆精品国产91久久久| 亚洲视频日本| 极品少妇一区二区三区精品视频| 精品国精品自拍自在线| 亚洲一区免费| 成人美女视频在线观看18| 一区二区三区四区国产精品| 日韩一区二区三区四区 | 欧美草草影院在线视频| 国产精品一区视频网站| 波多野结衣中文字幕一区二区三区| 亚洲欧美日韩精品久久久久| 8v天堂国产在线一区二区| 亚洲国产1区| 成人毛片老司机大片|