這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 Vue2 將在 2023 年年底停止維護了,但是 Vue2 的代碼卻不會在 2023 年消失,還會越來越多;難以想象幾十萬行或者幾百萬行的 Vue2 代碼遷移到 Vue3,這是不可能辦到的; 老一點的前端程式員肯定經歷過把大型項目從 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
前言
Vue2 將在 2023 年年底停止維護了,但是 Vue2 的代碼卻不會在 2023 年消失,還會越來越多;難以想象幾十萬行或者幾百萬行的 Vue2 代碼遷移到 Vue3,這是不可能辦到的;
老一點的前端程式員肯定經歷過把大型項目從 jQuery 遷移到 Vue/React/Angular 的經歷,那是一次思想的大變革,也是生產效率的一次大革新,但是這一次就不一樣了,Vue2 遷移到 Vue3 雖然優點很多,但是這不足以說服老闆們花費$去讓你進行重構;
既然 Vue2 還能用,那我就想把他用到極致,日常中最常用的就是 Table 組件,所以 Table 組件出現屎山的概率大大增加了,再加上 UI 框架的加持,這個屎山就被放大了!Vue2 寫後臺也就是這幾個 UI 框架:Antd-vue、Element、iView,兩款是個人開發者出品,一款是餓了麽出品,來看看他們的 Table 組件
iView
iView Table 屎山
為什麼先說 iView,因為 iView 早期版本裡面的 Table 組件有一個很奇葩的設定那就是使用 render 函數來渲染 columns,而我們剛好用的 iView 版本就是這個時期的,後面也難以再升級,這個時候就產生大量屎山代碼了:
比方說Table 每一行後面有四個操作按鈕,那麼就需要這樣寫:render:(h,{row})=>{ return h('div',[ h('a',{ props:{ }, styles:{ }, on:{ click:()=>{ } } },'新增'), h('a',{ class:'xxx' },'修改'), h('a',{ class:'xxx', on:{ click:()=>{ Modal.confirm({ ... }) } } },'刪除'), h('a',{ class:'xxx' },'配置'), ]) }
有沒有感覺到特別醜陋,而且寫起來效率也十分低下,好像回到了原始社會;原始社會裡面大家鑽木取火,現在一個打火機就能夠搞定,而這個 Table 裡面的 Column 的設定就像是鑽木取火了,一個 Colmun 還好,如果所有 Column 都這樣寫,並且都定義在 data 裡面,想象一下一個 data 都定義了幾百行,這是不是最大的屎山呢?
這個屎山有辦法破解嗎?答案是有的,總共有兩個方向,一個方向是編譯優化,一個方向是利用 scopedSlots
編譯優化
回憶一下 React,每一個 jsx 代碼其實都等同於 createElement("div",{},"xxxx"),與上面的代碼類似,那麼在 Vue 裡面也可以寫 jsx,然後編譯為 h 函數,按照這種思路上面的代碼就可以優化為:
render:(h,{row})=>{ return <div> <a>新增</a> <a>修改</a> <a onClick={()=> this.onDelete(row)}>刪除</a> <a>配置</a> </div> }
這樣的話看起來就舒服很多了,但是有人會說了:在 Vue 裡邊寫 jsx,又有 template 又有 jsx 搞得是四不像,不倫不類了,這種方式我不喜歡,還是想利用 Vue 的特性,要麼我就還是情願回到原始社會去鑽木取火;那麼下麵一種方式就是 scopedSlots
scopedSlots 優化
先說怎麼用:在 columns 數組中增加一個參數 slot,然後定義作用域插槽:
<template> <Table :columns="columns"> <template #actions="{row,index}"> <a>新增</a> <a>修改</a> <a @click="onDelete(row)"}>刪除</a> <a>配置</a> </template> </Table> <template> <script> export default{ data(){ return { columns:[{ title:'操作', slot:'actions', key:'actions' ]} } } </script>再來看看Table 是如何支持這個功能的呢,大概思路就是在遍歷 columns 時會判斷一下 slot 是否存在,如果存在則展示作用於插槽,如果不存在則走原來的邏輯,下麵貼了一些偽代碼:
<td> <!-- 如果遍歷 colums 之後 slot 屬性存在,那麼渲染 slot,否則按照預設規則渲染 --> <slot v-if="slotName" :name="slotName" v-bind="{row,index}"/> <span v-else>...</span> </td>
學會了這兩種優化方式,領導再也不用擔心我堆屎山了!
Element
再看看 Element 中的Table,舒服多了有沒有:
不用把 Column 的配置與 內容割裂開,可以都放在 template 中書寫,這樣比上面的方式靈活多了,而且還極大減少了屎山代碼的形成,對比下來還是 Element 的 Table 組件更為成熟好用;
antd-vue
最後一個是 antd-vue,看一下 antd-vue 中 Table 的用法,這不就和上面講到的 scopedSlots 優化那種用法類似嗎?
翻到後面,可以看到一個 template 風格 API,與 Element 這種用法類似,但是後面緊接著提示:不推薦使用,會有一定的性能損耗。
,為什麼會有性能損耗呢?那麼 Element 這麼用會有性能損耗嗎?
後記
到這裡 Vue2 中的 Table 屎山就結束了,再回頭看看 iView 直接暴露 h 函數,雖然極大地增加了 Column 定義的靈活度,但是增加了很多無效代碼就好像回到原始社會一樣,也增加了不少的屎山代碼;在日常開發過程中,很多需求都是趕著工期完成的或者倒排工期完成,根本沒有時間去思考怎麼優化,這個時候 UI 框架對於效率的影響就被放大了;好的 UI 框架不僅能夠提供好的交互效果,還能從 API 層面去約束開發者,讓開發者儘可能寫出好的代碼,另外就是讓開發者儘可能少寫代碼;