<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          分享 一些 Vue3 相關(guān)的實(shí)用技巧,也許你可能還不知道

          共 5455字,需瀏覽 11分鐘

           ·

          2021-12-24 20:44

          作者:月夕 (已獲轉(zhuǎn)載授權(quán))

          鏈接:https://juejin.cn/post/7005880217684148231

          演示代碼使用 Vue3 + ts + Vite 編寫,但是也會列出適用于 Vue2 的優(yōu)化技巧,如果某個優(yōu)化只適用于 Vue3 或者 Vue2,我會在標(biāo)題中標(biāo)出來。

          一、代碼優(yōu)化

          v-for 中使用 key

          使用?v-for?更新已渲染的元素列表時,默認(rèn)用就地復(fù)用策略;列表數(shù)據(jù)修改的時候,他會根據(jù)?key?值去判斷某個值是否修改,如果修改,則重新渲染這一項(xiàng),否則復(fù)用之前的元素;

          使用key的注意事項(xiàng):

          • 不要使用可能重復(fù)的或者可能變化?key?值(控制臺也會給出提醒)
          • 如果數(shù)組中的數(shù)據(jù)有狀態(tài)需要維持時(例如輸入框),不要使用數(shù)組的?index?作為?key?值,因?yàn)槿绻跀?shù)組中插入或者移除一個元素時,其后面的元素 index 將會變化,這回讓vue進(jìn)行原地復(fù)用時錯誤的綁定狀態(tài)。
          • 如果數(shù)組中沒有唯一的 key值可用,且數(shù)組更新時不是全量更新而是采用類似push,splice來插入或者移除數(shù)據(jù)時,可以考慮對其添加一個 key 字段,值為 Symbol() 即可保證唯一。

          何時使用何種key?

          這是一個非常有考究的問題,首先你要知道 vue 中的?原地復(fù)用?(大概就是?虛擬dom?變化時,兩個?虛擬dom節(jié)點(diǎn)?的?key如果一樣就不會重新創(chuàng)建節(jié)點(diǎn),而是修改原來的節(jié)點(diǎn))

          當(dāng)我們渲染的數(shù)據(jù)不需要保持狀態(tài)時,例如常見的單純的表格分頁渲染(不包含輸入,只是展示)、下拉加載更多等場景,那么使用?index?作為?key?再好不過,因?yàn)檫M(jìn)入下一頁或者上一頁時就會原地復(fù)用之前的節(jié)點(diǎn),而不是重新創(chuàng)建,如果使用唯一的?id?作為?key?反而會重新創(chuàng)建dom,性能相對較低。

          此外使用?index?作為?key?我還應(yīng)該要盡量避免對數(shù)組的中間進(jìn)行 增加/刪除 等會影響后面元素key變化的操作。這會讓 vue 認(rèn)為后面所有元素都發(fā)生了變化,導(dǎo)致多余的對比和原地復(fù)用。

          所以使用 index 作為 key 需要滿足:

          1. 數(shù)據(jù)沒有獨(dú)立的狀態(tài)
          2. 數(shù)據(jù)不會進(jìn)行 增加/刪除 等會影響后面元素key變化的操作

          哪何時使用 id 作為 key 呢?

          對于大多數(shù)數(shù)據(jù)的?id?都是唯一的,這無疑的一個?key?的優(yōu)選答案。對于任何大多數(shù)情況使用?id?作為?key?都不會出現(xiàn)上面?bug。但是如果你需要考慮性能問題,那就就要思考是否應(yīng)該使用原地復(fù)用了。

          同樣是上面的分頁數(shù)據(jù)展示,如果使用?id?作為?key?,可想而知每一頁的每一條數(shù)據(jù)?id?都是不一樣的,所以當(dāng)換頁時兩顆?虛擬DOM樹?的節(jié)點(diǎn)的?key?完全不一致,vue?就會移除原來的節(jié)點(diǎn)然后創(chuàng)建新的節(jié)點(diǎn)。可想而知效率會更加低下。但是他也有它的優(yōu)點(diǎn)。唯一的?key?可以幫助?diff?更加精確的為我們綁定狀態(tài),這尤其適合數(shù)據(jù)有獨(dú)立的狀態(tài)的場景,例如帶輸入框或者單選框的列表數(shù)據(jù)。

          所以何時使用?id?作為?key?只有一點(diǎn):

          1. 無法使用?index?作為?key?的時候

          v-if/v-else-if/v-else 中使用 key

          可能很多人都會忽略這個點(diǎn)

          原因:默認(rèn)情況下,Vue 會盡可能高效的更新 DOM。這意味著其在相同類型的元素之間切換時,會修補(bǔ)已存在的元素,而不是將舊的元素移除然后在同一位置添加一個新元素。如果本不相同的元素被識別為相同,則會出現(xiàn)意料之外的副作用。

          如果只有一個 v-if ,沒有 v-else 或者 v-if-else的話,就沒有必要加 key 了

          相對于 v-for 的 key, v-if/v-else-if/v-else 中的 key 相對簡單,我們可以直接寫入固定的字符串或者數(shù)組即可

          ??<transition>
          ????<button
          ??????v-if="isEditing"
          ??????v-on:click="isEditing?=?false"
          ????>

          ??????Save
          ????button>
          ????<button
          ??????v-else
          ??????v-on:click="isEditing?=?true"
          ????>

          ??????Edit
          ????button>
          ??transition>
          .v-enter-active,?.v-leave-active?{
          ??transition:?all?1s;
          }
          .v-enter,?.v-leave-to?{
          ??opacity:?0;
          ??transform:?translateY(30px);
          }
          .v-leave-active?{
          ??position:?absolute;
          }

          例如對于上面的代碼, 你會發(fā)現(xiàn)雖然對 button 添加了 過渡效果, 但是如果不添加 key 切換時是無法觸發(fā)過渡的

          v-for 和 v-if 不要一起使用(Vue2)

          此優(yōu)化技巧僅限于Vue2,Vue3 中對 v-for 和 v-if 的優(yōu)先級做了調(diào)整

          這個大家都知道

          永遠(yuǎn)不要把?v-if?和?v-for?同時用在同一個元素上。?引至?Vue2.x風(fēng)格指南[1]

          原因是?v-for?的 優(yōu)先級高于?v-if,所以當(dāng)它們使用再同一個標(biāo)簽上是,每一個渲染都會先循環(huán)再進(jìn)行條件判斷

          注意:?Vue3 中?v-if?優(yōu)先級高于?v-for,所以當(dāng)?v-for?和?v-if?一起使用時效果類似于?Vue2?中把?v-if?上提的效果

          例如下面這段代碼在?Vue2?中是不被推薦的,Vue?也會給出對應(yīng)的警告

          <ul>
          ??<li?v-for="user?in?users"?v-if="user.active">
          ????{{?user.name?}}
          ??li>
          ul>

          我們應(yīng)該盡量將?v-if?移動到上級 或者 使用 計(jì)算屬性來處理數(shù)據(jù)

          <ul?v-if="active">
          ??<li?v-for="user?in?users">
          ????{{?user.name?}}
          ??li>
          ul>

          如果你不想讓循環(huán)的內(nèi)容多出一個無需有的上級容器,那么你可以選擇使用?template?來作為其父元素,template?不會被瀏覽器渲染為?DOM?節(jié)點(diǎn)

          如果我想要判斷遍歷對象里面每一項(xiàng)的內(nèi)容來選擇渲染的數(shù)據(jù)的話,可以使用?computed?來對遍歷對象進(jìn)行過濾

          //?js
          let?usersActive?=?computed(()=>users.filter(user?=>?user.active))

          //?template
          <ul>
          ????<li?v-for="user?in?usersActive">
          ??????{{?user.name?}}
          ????li>
          ul>

          合理的選擇 v-if 和 v-show

          v-if?和?v-show?的區(qū)別相比大家都非常熟悉了;v-if?通過直接操作 DOM 的刪除和添加來控制元素的顯示和隱藏;v-show?是通過控制 DOM 的?display?CSS熟悉來控制元素的顯示和隱藏

          由于對 DOM 的 添加/刪除 操作性能遠(yuǎn)遠(yuǎn)低于操作 DOM 的 CSS 屬性

          所以當(dāng)元素需要頻繁的 顯示/隱藏 變化時,我們使用?v-show?來提高性能。

          當(dāng)元素不需要頻繁的 顯示/隱藏 變化時,我們通過?v-if?來移除 DOM 可以節(jié)約掉瀏覽器渲染這個的一部分DOM需要的資源

          使用簡單的 計(jì)算屬性

          應(yīng)該把復(fù)雜計(jì)算屬性分割為盡可能多的更簡單的 property。

          • 易于測試

            當(dāng)每個計(jì)算屬性都包含一個非常簡單且很少依賴的表達(dá)式時,撰寫測試以確保其正確工作就會更加容易。

          • 易于閱讀

            簡化計(jì)算屬性要求你為每一個值都起一個描述性的名稱,即便它不可復(fù)用。這使得其他開發(fā)者 (以及未來的你) 更容易專注在他們關(guān)心的代碼上并搞清楚發(fā)生了什么。

          • 更好的“擁抱變化”

            任何能夠命名的值都可能用在視圖上。舉個例子,我們可能打算展示一個信息,告訴用戶他們存了多少錢;也可能打算計(jì)算稅費(fèi),但是可能會分開展現(xiàn),而不是作為總價的一部分。

            小的、專注的計(jì)算屬性減少了信息使用時的假設(shè)性限制,所以需求變更時也用不著那么多重構(gòu)了。

          引至?Vue2風(fēng)格指南[2]

          computed 大家后很熟悉, 它會在其表達(dá)式中依賴的響應(yīng)式數(shù)據(jù)發(fā)送變化時重新計(jì)算。如果我們在一個計(jì)算屬性中書寫了比較復(fù)雜的表達(dá)式,那么其依賴的響應(yīng)式數(shù)據(jù)也任意變得更多。當(dāng)其中任何一個依賴項(xiàng)變化時整個表達(dá)式都需要重新計(jì)算

          let?price?=?computed(()=>{
          ??let?basePrice?=?manufactureCost?/?(1?-?profitMargin)
          ??return?(
          ??????basePrice?-
          ??????basePrice?*?(discountPercent?||?0)
          ??)
          })

          當(dāng) manufactureCost、profitMargin、discountPercent 中任何一個變化時都會重新計(jì)算整個 price。

          但是如果我們改成下面這樣

          let?basePrice?=?computed(()?=>?manufactureCost?/?(1?-?profitMargin))
          let?discount?=?computed(()?=>?basePrice?*?(discountPercent?||?0))
          let?finalPrice?=?computed(()?=>?basePrice?-?discount)

          如果當(dāng) discountPercent 變化時,只會 重新計(jì)算 discount 和 finalPrice,由于?computed?的緩存特性,不會重新計(jì)算 basePrice

          functional 函數(shù)式組件(Vue2)

          注意,這僅僅在 Vue2 中被作為一種優(yōu)化手段,在 3.x 中,有狀態(tài)組件和函數(shù)式組件之間的性能差異已經(jīng)大大減少,并且在大多數(shù)用例中是微不足道的。因此,在 SFCs 上使用?functional?的開發(fā)人員的遷移路徑是刪除該 attribute,并將?props?的所有引用重命名為?$props,將?attrs?重命名為?$attrs。

          優(yōu)化前

          <template>
          ????<div?class="cell">
          ????????<div?v-if="value"?class="on">div>
          ????????<section?v-else?class="off">section>
          ????div>
          template>

          <script>
          export?default?{
          ????props:?['value'],
          }
          script>

          優(yōu)化后

          <template?functional>
          ????<div?class="cell">
          ????????<div?v-if="props.value"?class="on">div>
          ????????<section?v-else?class="off">section>
          ????div>
          template>

          <script>
          export?default?{
          ????props:?['value'],
          }
          script>
          • 沒有this(沒有實(shí)例)
          • 沒有響應(yīng)式數(shù)據(jù)

          拆分組件

          什么?你寫的一個vue文件有一千多行代碼???

          合理的拆分組件不僅僅可以優(yōu)化性能,還能夠讓代碼更清晰可讀。單一功能原則嘛

          源自?slides.com/akryum/vuec…[3]

          優(yōu)化前

          <template>
          ??<div?:style="{?opacity:?number?/?300?}">
          ????<div>{{?heavy()?}}div>
          ??div>
          template>

          <script>
          export?default?{
          ??props:?['number'],
          ??methods:?{
          ????heavy?()?{?/*?HEAVY?TASK?*/?}
          ??}
          }
          script>

          優(yōu)化后

          <template>
          ??<div?:style="{?opacity:?number?/?300?}">
          ????<ChildComp/>
          ??div>
          template>

          <script>
          export?default?{
          ??props:?['number'],
          ??components:?{
          ????ChildComp:?{
          ??????methods:?{
          ????????heavy?()?{?/*?HEAVY?TASK?*/?}
          ??????},
          ??????render?(h)?{
          ????????return?h('div',?this.heavy())
          ??????}
          ????}
          ??}
          }
          script>

          由于 Vue 的更新是組件粒度的,雖然每一幀都通過數(shù)據(jù)修改導(dǎo)致了父組件的重新渲染,但是?ChildComp?卻不會重新渲染,因?yàn)樗膬?nèi)部也沒有任何響應(yīng)式數(shù)據(jù)的變化。所以優(yōu)化后的組件不會在每次渲染都執(zhí)行耗時任務(wù)

          使用局部變量

          優(yōu)化前

          <template>
          ??<div?:style="{?opacity:?start?/?300?}">{{?result?}}div>
          template>

          <script>
          import?{?heavy?}?from?'@/utils'

          export?default?{
          ??props:?['start'],
          ??computed:?{
          ????base?()?{?return?42?},
          ????result?()?{
          ??????let?result?=?this.start
          ??????for?(let?i?=?0;?i?1000
          ;?i++)?{
          ????????result?+=?heavy(this.base)
          ??????}
          ??????return?result
          ????}
          ??}
          }
          script>

          優(yōu)化后

          <template>
          ??<div?:style="{?opacity:?start?/?300?}">
          ????{{?result?}}div>
          template>

          <script>
          import?{?heavy?}?from?'@/utils'

          export?default?{
          ??props:?['start'],
          ??computed:?{
          ????base?()?{?return?42?},
          ????result?()?{
          ??????const?base?=?this.base
          ??????let?result?=?this.start
          ??????for?(let?i?=?0;?i?1000
          ;?i++)?{
          ????????result?+=?heavy(base)
          ??????}
          ??????return?result
          ????}
          ??}
          }
          script>

          這里主要是優(yōu)化前后的組件的計(jì)算屬性?result?的實(shí)現(xiàn)差異,優(yōu)化前的組件多次在計(jì)算過程中訪問?this.base,而優(yōu)化后的組件會在計(jì)算前先用局部變量?base,緩存?this.base,后面直接訪問?base

          那么為啥這個差異會造成性能上的差異呢,原因是你每次訪問?this.base?的時候,由于?this.base?是一個響應(yīng)式對象,所以會觸發(fā)它的?getter,進(jìn)而會執(zhí)行依賴收集相關(guān)邏輯代碼。類似的邏輯執(zhí)行多了,像示例這樣,幾百次循環(huán)更新幾百個組件,每個組件觸發(fā)?computed?重新計(jì)算,然后又多次執(zhí)行依賴收集相關(guān)邏輯,性能自然就下降了。

          從需求上來說,this.base?執(zhí)行一次依賴收集就夠了,把它的?getter?求值結(jié)果返回給局部變量?base,后續(xù)再次訪問?base?的時候就不會觸發(fā)?getter,也不會走依賴收集的邏輯了,性能自然就得到了提升。

          引至?揭秘 Vue.js 九個性能優(yōu)化技巧[4]

          使用 KeepAlive

          在一些渲染成本比較高的組件需要被經(jīng)常切換時,可以使用?keep-alive?來緩存這個組件

          而在使用?keep-alive?后,被?keep-alive?包裹的組件在經(jīng)過第一次渲染后,的?vnode?以及 DOM 都會被緩存起來,然后再下一次再次渲染該組件的時候,直接從緩存中拿到對應(yīng)的?vnode?和 DOM,然后渲染,并不需要再走一次組件初始化,render?和?patch?等一系列流程,減少了?script?的執(zhí)行時間,性能更好。

          注意:?濫用 keep-alive 只會讓你的應(yīng)用變得更加卡頓,因?yàn)樗麜L期占用較大的內(nèi)存

          事件的銷毀

          當(dāng)一個組件被銷毀時,我們應(yīng)該清除組件中添加的 全局事件 和 定時器 等來防止內(nèi)存泄漏

          Vue3 的 HOOK 可以讓我們將事件的聲明和銷毀寫在一起,更加可讀

          function?scrollFun(){?/*?...?*/}
          document.addEventListener("scroll",?scrollFun)

          onBeforeUnmount(()=>{
          ??document.removeEventListener("scroll",?scrollFun)
          })

          Vue2 依然可以通過?$once?來做到這樣的效果,當(dāng)然你也可以在?optionsAPI?beforeDestroy 中銷毀事件,但是我更加推薦前者的寫法,因?yàn)楹笳邥屜嗤δ艿拇a更分散

          function?scrollFun(){?/*?...?*/}
          document.addEventListener("scroll",?scrollFun)

          this.$once('hook:beforeDestroy',?()=>{
          ??document.removeEventListener("scroll",?scrollFun)
          })
          function?scrollFun(){?/*?...?*/}

          export?default?{
          ??created()?{
          ????document.addEventListener("scroll",?scrollFun)
          ??},
          ??beforeDestroy(){
          ????document.removeEventListener("scroll",?scrollFun)
          ??}
          }

          圖片加載

          圖片懶加載:適用于頁面上有較多圖片且并不是所有圖片都在一屏中展示的情況,vue-lazyload 插件給我們提供了一個很方便的圖片懶加載指令 v-lazy

          但是并不是所有圖片都適合使用懶加載,例如 banner、相冊等 更加推薦使用圖片預(yù)加載技術(shù),將當(dāng)前展示圖片的前一張和后一張優(yōu)先下載。

          采用合理的數(shù)據(jù)處理算法

          這個相對比較考驗(yàn) 數(shù)據(jù)結(jié)構(gòu)和算法 的功底

          例如一個將數(shù)組轉(zhuǎn)化為多級結(jié)構(gòu)的方法

          /**
          ?*?數(shù)組轉(zhuǎn)樹形結(jié)構(gòu),時間復(fù)雜度O(n)
          ?*?@param?list?數(shù)組
          ?*?@param?idKey?元素id鍵
          ?*?@param?parIdKey?元素父id鍵
          ?*?@param?parId?第一級根節(jié)點(diǎn)的父id值
          ?*?@return?{[]}
          ?*/

          function?listToTree?(list,idKey,parIdKey,parId)?{
          ????let?map?=?{};
          ????let?result?=?[];
          ????let?len?=?list.length;

          ????//?構(gòu)建map
          ????for?(let?i?=?0;?i?????????//將數(shù)組中數(shù)據(jù)轉(zhuǎn)為鍵值對結(jié)構(gòu)?(這里的數(shù)組和obj會相互引用,這是算法實(shí)現(xiàn)的重點(diǎn))
          ????????map[list[i][idKey]]?=?list[i];
          ????}

          ????//?構(gòu)建樹形數(shù)組
          ????for(let?i=0;?i?????????let?itemParId?=?list[i][parIdKey];
          ????????//?頂級節(jié)點(diǎn)
          ????????if(itemParId?===?parId)?{
          ????????????result.push(list[i]);
          ????????????continue;
          ????????}
          ????????//?孤兒節(jié)點(diǎn),舍棄(不存在其父節(jié)點(diǎn))
          ????????if(!map[itemParId]){
          ????????????continue;
          ????????}
          ????????//?將當(dāng)前節(jié)點(diǎn)插入到父節(jié)點(diǎn)的children中(由于是引用數(shù)據(jù)類型,obj中對于節(jié)點(diǎn)變化,result中對應(yīng)節(jié)點(diǎn)會跟著變化)
          ????????if(map[itemParId].children)?{
          ????????????map[itemParId].children.push(list[i]);
          ????????}?else?{
          ????????????map[itemParId].children?=?[list[i]];
          ????????}
          ????}
          ????return?result;
          }

          其他

          除了上面說的方法以外還有很多優(yōu)化技巧,只是我在項(xiàng)目并不是太常用??

          • 凍結(jié)對象(避免不需要響應(yīng)式的數(shù)據(jù)變成響應(yīng)式)
          • 長列表渲染-分批渲染
          • 長列表渲染-動態(tài)渲染(vue-virtual-scroller[5]
          • ...

          二、 首屏/體積優(yōu)化

          我在項(xiàng)目中關(guān)于首屏優(yōu)化主要有以下幾個優(yōu)化方向

          • 體積
          • 代碼分割
          • 網(wǎng)絡(luò)

          體積優(yōu)化

          • 壓縮打包代碼:?webpack?和?vite?的生產(chǎn)環(huán)境打包默認(rèn)就會壓縮你的代碼,這個一般不需要特殊處理,webpack?也可以通過對應(yīng)的壓縮插件手動實(shí)現(xiàn)

          • 取消?source-map:?可以查看你的打包產(chǎn)物中是否有 .map 文件,如果有你可以將?source-map?的值設(shè)置為false或者空來關(guān)閉代碼映射(這個占用的體積是真的大)

          • 打包啟用?gizp?壓縮:?這個需要服務(wù)器也開啟允許?gizp?傳輸,不然啟用了也沒啥用(?webpack?有對應(yīng)的?gzip?壓縮插件,不太版本的?webpack?壓縮插件可能不同,建議先到官網(wǎng)查詢)

          代碼分割

          代碼分割的作用的將打包產(chǎn)物分割為一個一個的小產(chǎn)物,其依賴?esModule。所以當(dāng)你使用?import()?函數(shù)來導(dǎo)入一個文件或者依賴,那么這個文件或者依賴就會被單獨(dú)打包為一個小產(chǎn)物。路由懶加載?和?異步組件?都是使用這個原理。

          • 路由懶加載
          • 異步組件

          對于 UI庫 我一般不會使用按需加載組件,而是比較喜歡 CDN 引入的方式來優(yōu)化。

          網(wǎng)絡(luò)

          CDN:?首先就是上面的說的 CDN 引入把,開發(fā)階段使用本地庫,通過配置?外部擴(kuò)展(Externals)?打包時來排除這些依賴。然后在 html 文件中通過 CDN 的方式來引入它們

          Server Push:?HTTP2已經(jīng)相對成熟了;經(jīng)過上面的 CDN 引入,我們可以對網(wǎng)站使用 HTTP2 的 Server Push 功能來讓瀏覽器提前加載 這些 CDN 和 其他文件。

          開啟 gzip:?這個上面已經(jīng)說過了,其原理就是當(dāng)客戶端和服務(wù)端都支持 gzip 傳輸時,服務(wù)端會優(yōu)先發(fā)送經(jīng)過 gzip 壓縮過的文件,然后客戶端接收到在進(jìn)行解壓。

          開啟緩存:?一般我使用的是協(xié)商緩存,但是這并不適用于所有情況,例如對于使用了 Server Push 的文件,就不能隨意的修改其文件名。所以我一般還會將生產(chǎn)的主要文件固定文件名

          參考資料

          [1]

          https://cn.vuejs.org/v2/style-guide/#%E9%81%BF%E5%85%8D-v-if-%E5%92%8C-v-for-%E7%94%A8%E5%9C%A8%E4%B8%80%E8%B5%B7%E5%BF%85%E8%A6%81:?https://link.juejin.cn?target=https%3A%2F%2Fcn.vuejs.org%2Fv2%2Fstyle-guide%2F%23%25E9%2581%25BF%25E5%2585%258D-v-if-%25E5%2592%258C-v-for-%25E7%2594%25A8%25E5%259C%25A8%25E4%25B8%2580%25E8%25B5%25B7%25E5%25BF%2585%25E8%25A6%2581

          [2]

          https://cn.vuejs.org/v2/style-guide/#%E7%AE%80%E5%8D%95%E7%9A%84%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7%E5%BC%BA%E7%83%88%E6%8E%A8%E8%8D%90:?https://link.juejin.cn?target=https%3A%2F%2Fcn.vuejs.org%2Fv2%2Fstyle-guide%2F%23%25E7%25AE%2580%25E5%258D%2595%25E7%259A%2584%25E8%25AE%25A1%25E7%25AE%2597%25E5%25B1%259E%25E6%2580%25A7%25E5%25BC%25BA%25E7%2583%2588%25E6%258E%25A8%25E8%258D%2590

          [3]

          https://slides.com/akryum/vueconfus-2019#/4/0/3:?https://link.juejin.cn?target=https%3A%2F%2Fslides.com%2Fakryum%2Fvueconfus-2019%23%2F4%2F0%2F3

          [4]

          https://juejin.cn/post/6922641008106668045:?https://juejin.cn/post/6922641008106668045

          [5]

          https://github.com/Akryum/vue-virtual-scroller:?https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2FAkryum%2Fvue-virtual-scroller

          瀏覽 63
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  男男射精网站18 | 国产成人精品 视频 | 日韩AV资源 | 欧美午夜精品爱爱 | 精品人妻无码一区二区三区91电影 |