vs code vue插件_干货分享 | Vue框架常见问题浅谈
友情提示:全文7800多文字,預計閱讀時間10分鐘
Vue是一套用于構建用戶界面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注視圖層,不僅易于上手,還便于與第三方庫或既有項目整合。另一方面,當與現代化的工具鏈以及各種支持類庫結合使用時,Vue 也完全能夠為復雜的單頁應用提供驅動。使用其進行前后端分離開發前端業務平臺,不斷摸索踩坑之后,總結出如下幾點Vue項目開發中常見的問題及解決辦法,希望與君共同探討。
列表進入詳情頁的傳參問題
本地開發環境請求服務器接口跨域的問題
axios封裝和api接口的統一管理
UI庫的按需加載
如何優雅的只在當前頁面中覆蓋ui庫中組件的樣式
定時器問題
rem文件的導入問題
Vue-Awesome-Swiper基本能解決你所有的輪播需求
打包后生成很大的.map文件的問題
fastClick的300ms延遲解決方案
組件中寫選項的順序
路由懶加載(也叫延遲加載)
開啟gzip壓縮代碼
詳情頁返回列表頁緩存數據和瀏覽位置、其他頁面進入列表頁刷新數據的實踐
css的scoped私有作用域和深度選擇器
hiper打開速度測試
路由的拆分管理
可選鏈操作符
利用閉包構造map緩存數據
列表進入詳情頁的傳參問題
例如租戶列表頁面前往租戶詳情頁面,需要傳一個租戶id;
頁面的路徑為http://localhost:8080/#/detail?code=1,可以看到傳了一個參數code=1,并且就算刷新頁面id也還會存在。此時在頁面可以通過code來獲取對應的詳情數據,獲取code的方式是this.$route.query.code
vue傳參方式有:query、params+動態路由傳參。
說下兩者的區別:
1、query通過path切換路由,params通過name切換路由
2、query通過this.$route.query來接收參數,params通過this.$route.params來接收參數。
3、query傳參的url展現方式:
/detail?code=1&user=123&identity=1&更多參數
params+動態路由的url方式:/detail/123
4、params動態路由傳參,一定要在路由中定義參數,然后在路由跳轉的時候必須要加上參數,否則就是空白頁面:
注意,params傳參時,如果沒有在路由中定義參數,也是可以傳過去的,同時也能接收到,但是一旦刷新頁面,這個參數就不存在了。這對于需要依賴參數進行某些操作的行為是行不通的,因為你總不可能要求用戶不能刷新頁面吧。例如:
本地開發環境請求服務器接口跨域的問題
上面的這個報錯大家都不會陌生,報錯是說沒有訪問權限(跨域問題)。本地開發項目請求服務器接口的時候,因為客戶端的同源策略,導致了跨域的問題。
下面先演示一個沒有配置允許本地跨域的的情況:
可以看到,此時我們點擊獲取數據,瀏覽器提示我們跨域了。所以我們訪問不到數據。
那么接下來我們演示設置允許跨域后的數據獲取情況:
注意:配置好后一定要關閉原來的server,重新npm run dev啟動項目。不然無效。
我們在1處設置了允許本地跨域,在2處,要注意我們訪問接口時,寫的是/api,此處的/api指代的就是我們要請求的接口域名。如果我們不想每次接口都帶上/api,可以更改axios的默認配置axios.defaults.baseURL = '/api';
這樣,我們請求接口就可以直接this.$axios.get('app.php?m=App&c=Index&a=index'),很簡單有木有。此時如果你在network中查看xhr請求,你會發現顯示的是localhost:8080/api的請求地址。這樣沒什么大驚小怪的,代理而已:
好了,最后附上proxyTable的代碼:
注意:配置好后一定要關閉原來的server,重新npm run dev啟動項目。不然無效。
axios封裝和api接口的統一管理
axios的封裝,主要是用來幫我們進行請求的攔截和響應的攔截。
在請求的攔截中我們可以攜帶userToken,post請求頭、qs對post提交數據的序列化等。
在響應的攔截中,我們可以進行根據狀態碼來進行錯誤的統一處理等等。
axios接口的統一管理,是做項目時必須的流程。這樣可以方便我們管理我們的接口,在接口更新時我們不必再返回到我們的業務代碼中去修改接口。
由于這里內容稍微多一些,放在另一篇文章。
UI庫的按需加載
為什么要使用按需加載的方式而不是一次性全部引入,原因就不多說了。這里以Element 的按需加載為例,演示vue中ui庫怎樣進行按需加載:
安裝:npm i element-ui -S
安裝babel-plugin-import插件使其按需加載:npm i babel-plugin-import -D
?在 .babelrc文件中中添加插件配置:
在main.js中按需加載你需要的插件:
使用組件:
最后在在頁面中使用:
ps:除了elementUi庫外,像antiUi、vant等,很多ui庫都支持按需加載,可以去看文檔,上面都會有提到。基本都是通過安裝babel-plugin-import插件來支持按需加載的,使用方式與elementUi的如出一轍,可以去用一下。
如何優雅的只在當前頁面中覆蓋ui庫中組件的樣式
首先我們vue文件的樣式都是寫在標簽中的,加scoped是為了使得樣式只在當前頁面有效。那么問題來了,看圖:
我們正常寫的所有樣式,都會被加上[data-v-08ec2874]這個屬性(如上圖所示),但是第三方組件內部的標簽并沒有編譯為附帶[data-v-08ec2874]這個屬性。所以,我們想修改組件的樣式,就沒轍了。怎么辦呢,有些小伙伴給第三方組件寫個class,然后在一個公共的css文件中或者在當前頁面再寫一個沒有socped屬性的style標簽,然后直接在里面修改第三方組件的樣式。這樣不失為一個方法,但是存在全局污染和命名沖突的問題。約定特定的命名方式,可以避免命名沖突。但是還是不夠優雅。
作為一名優(強)秀(迫)的(癥)前(患)端(者),怎么能允許這種情況出現呢?好了,下面說下優雅的解決方式:
通過深度選擇器解決。例如修改上圖中組件里的el-tab-item類的樣式,可以這樣做:
編譯后的結果就是:
這樣就不會給el-tab也添加[data-v-08ec2874]屬性了。至此你可以愉快的修改第三方組件的樣式了。
當然了這里的深度選擇器/deep/是因為我用的less語言,如果你沒有使用less/sass等,可以用>>>符號。
定時器問題
我在頁面a寫一個定時,讓他每秒鐘打印一個1,然后跳轉到頁面b,此時可以看到,定時器依然在執行。這樣是非常消耗性能的。
解決方案1:
首先我在data函數里面進行定義定時器名稱:
然后這樣使用定時器:
最后在beforeDestroy()生命周期內清除定時器:
方案1有兩點不好的地方,引用尤大的話來說就是:
它需要在這個組件實例中保存這個 timer,如果可以的話最好只有生命周期鉤子可以訪問到它。這并不算嚴重的問題,但是它可以被視為雜物。
我們的建立代碼獨立于我們的清理代碼,這使得我們比較難于程序化的清理我們建立的所有東西。
解決方案2:
該方法是通過$once這個事件偵聽器器在定義完定時器之后的位置來清除定時器。以下是完整代碼:
類似于其他需要在當前頁面使用,離開需要銷毀的組件(例如一些第三方庫的picker組件等等),都可以使用此方式來解決離開后以后在背后運行的問題。
綜合來說,我們更推薦使用解決方案2,使得代碼可讀性更強,一目了然。
如果不清楚$once、$on、$off的使用,這里送上官網的地址教程,在程序化的事件偵聽器那里。(官網地址:https://cn.vuejs.org/v2/guide/)
rem文件的導入問題
我們在做手機端時,適配是必須要處理的一個問題。例如,我們處理適配的方案就是通過寫一個rem.js,原理很簡單,就是根據網頁尺寸計算html的font-size大小,基本上小伙伴們都知道,這里直接附上代碼,不多做介紹。
這里說下怎么引入的問題,很簡單。在main.js中,直接import './config/rem'導入即可。import的路徑根據你的文件路徑去填寫。
打包后生成很大的.map文件的問題
項目打包后,代碼都是經過壓縮加密的,如果運行時報錯,輸出的錯誤信息無法準確得知是哪里的代碼報錯。?而生成的.map后綴的文件,就可以像未加密的代碼一樣,準確的輸出是哪一行哪一列有錯可以通過設置來不生成該類文件。但是我們在生產環境是不需要.map文件的,所以可以在打包時不生成這些文件:
在config/index.js文件中,設置productionSourceMap: false,就可以不生成.map文件。
fastClick的300ms延遲解決方案
開發移動端項目,點擊事件會有300ms延遲的問題。
這里只說下常見的解決思路,不管vue項目還是jq項目,都可以使用fastClick解決。
安裝?fastClick:
在main.js中引入fastClick和初始化:
組件中寫選項的順序
為什么選項要有統一的書寫順序呢?很簡單,就是要將選擇和認知成本最小化。
1、副作用?(觸發組件外的影響)
·? el
2、全局感知?(要求組件以外的知識)
·? name
·? parent
3、組件類型?(更改組件的類型)
·? functional
4、模板修改器?(改變模板的編譯方式)
·? delimiters
有時候我們使用"{{內容}}",當后臺的插值符跟現有的插值符有沖突時,這時就要改變我們的插值符
·? comments
5、模板依賴 (模板內使用的資源)
·? components
·? directives
·? filters
6、組合(向選項里合并屬性)
·? extends
·? mixins
7、接口(組件的接口)
·? inheritAttrs
·? model
·? props/propsData
8、本地狀態(本地的響應式屬性)
·? data
·? computed
9、事件(通過響應式事件觸發的回調)
·? watch
· 生命周期鉤子(按照它們被調用的順序)
-?beforeCreate-?created-?beforeMount-?mounted-?beforeUpdate-?updated-?activated-?deactivated-?beforeDestroy-?destroyed
10、非響應式的屬性(不依賴響應系統的實例屬性)
·? methods
11、渲染(組件輸出的聲明式描述)
·? template
·? render
·? renderError
查看打包后各文件的體積? 幫你快速定位大文件
如果你是vue-cli初始化的項目,會默認安裝webpack-bundle-analyzer插件,該插件可以幫助我們查看項目的體積結構對比和項目中用到的所有依賴。也可以直觀看到各個模塊體積在整個項目中的占比。
記得運行的時候先把之前**npm run dev**開啟的本地關掉。
路由懶加載(也叫延遲加載)
路由懶加載可以幫我們在進入首屏時不用加載過度的資源,從而減少首屏加載速度。
路由文件中,
非懶加載寫法:
路由懶加載寫法:
開啟gzip壓縮代碼
spa這種單頁應用,首屏由于一次性加載所有資源,所有首屏加載速度很慢。解決這個問題非常有效的手段之一就是前后端開啟gizp(其他還有緩存、路由懶加載等等)。gizp其實就是幫我們減少文件體積,能壓縮到30%左右,即100k的文件gizp后大約只有30k。
vue-cli初始化的項目中,是默認有此配置的,只需要開啟即可。但是需要先安裝插件:
然后在config/index.js中開啟即可:
現在打包的時候,除了會生成之前的文件,還是生成.gz結束的gzip過后的文件。具體實現就是如果客戶端支持gzip,那么后臺后返回gzip后的文件,如果不支持就返回正常沒有gzip的文件。
注意:這里前端進行的打包時的gzip,但是還需要后臺服務器的配置。配置是比較簡單的,配置幾行代碼就可以了,一般這個操作可以叫運維小哥哥小姐姐去搞一下,沒有運維的讓后臺去幫忙配置。
詳情頁返回列表頁緩存數據和瀏覽位置、
其他頁面進入列表頁刷新數據的實踐
這樣一個場景:有兩個頁面,用戶列表頁,用戶列表詳情頁。我們希望從用戶列表頁進入用戶列表詳情頁時,用戶列表詳情頁面要刷新數據,從用戶列表詳情頁進入詳情頁再返回到用戶列表詳情頁面時,我們不希望刷新,我們希望此時的分類頁面能夠緩存已加載的數據和自動保存用戶上次瀏覽的位置。
解決這種場景需求我們可以通過vue提供的keepAlive屬性。除此之外,還需要配合activated、beforeRouteLeave、beforeRouteEnter鉤子函數進行處理;如下:
CSS的scoped私有作用域和深度選擇器
大家都知道當?
編譯前:
編譯后:
其實是我們在寫的組件的樣式,添加了一個屬性而已,這樣就實現了所謂的私有作用域。但是也會有弊端,考慮到瀏覽器渲染各種 CSS 選擇器的方式,當 div { color: #409EFF }?設置了作用域時 (即與特性選擇器組合使用時) 會慢很多倍。如果你使用 class 或者 id 取而代之,比如 .user-manage-container { color: #409EFF },性能影響就會消除。所以,在你的樣式里,進來避免直接使用標簽,取而代之的你可以給標簽起個class名。
如果我們希望 scoped 樣式中的一個選擇器能夠作用得“更深”,例如影響子組件,你可以使用?>>>?操作符:
代碼將會編譯成:
而對于less或者sass等預編譯,是不支持>>>操作符的,可以使用/deep/來替換>>>操作符,例如:.parent /deep/ .child { /* ... */ }
Hiper:一款性能分析工具
如上圖,是hiper工具的測試結果,從中我們可以看到DNS查詢耗時、TCP連接耗時、第一個Byte到達瀏覽器的用時、頁面下載耗時、DOM Ready之后又繼續下載資源的耗時、白屏時間、DOM Ready 耗時、頁面加載總耗時。
在編輯器終端中全局安裝:
使用:**終端輸入命令:hiper 測試的網址
上述的用法示例,我直接拷貝的文檔說明,具體的可以看下文檔,這里送上鏈接。當我們項目打開速度慢時,這個工具可以幫助我們快速定位出到底在哪一步影響的頁面加載的速度。
平時我們查看性能的方式,是在performance和network中看數據,記錄下幾個關鍵的性能指標,然后刷新幾次再看這些性能指標。有時候我們發現,由于樣本太少,受當前「網絡」、「CPU」、「內存」的繁忙程度的影響很重,有時優化后的項目反而比優化前更慢。
如果有一個工具,一次性地請求N次網頁,然后把各個性能指標取出來求平均值,我們就能非常準確地知道這個優化是「正優化」還是「負優化」。hiper就是解決這個痛點的。
路由拆分管理
我這里說的路由拆分指的是將路由的文件,按照模塊拆分,這樣方便路由的管理,更主要的是方便多人開發。具體要不要拆分,那就要視你的項目情況來定了,如果項目較小的話,也就一二十個路由,那么是拆分是非常沒必要的。但倘若你開發一些功能點較多的C端項目,路由可以會有一百甚至幾百個,那么此時將路由文件進行拆分是很有必要的。不然,index.js文件中一大長串串串串串串的路由,也是很糟糕的。
首先我們在router文件夾中創建一個index.js作為路由的入口文件,然后新建一個modules文件夾,里面存放各個模塊的路由文件。例如這里儲存了一個user.js用戶模塊的路由文件和一個公共模塊的路由文件。下面直接上index.js吧,而后再簡單介紹:
首先引入vue和router最后導出,基本的操作。
這里把路由守衛router.beforeEach的操作寫了router的index.js文件中,有些人可能會寫在main.js中,這也沒有錯,只不過,個人而言,既然是路由的操作,還是放在路由文件中管理更好些。這里就順便演示了,如何在頁面切換時,自動修改頁面標題的操作。
而后引入你根據路由模塊劃分的各個js文件,然后在實例化路由的時候,在routes數組中,將導入的各個文件通過結構賦值的方法取出來。最終的結果和正常的寫法是一樣的。
然后看下我們導入的user.js:
這里就是將用戶模塊的路由放在一個數組中導出去。整個路由拆分的操作,不是vue的知識,就是一個es6導入導出和結構的語法。具體要不要拆分,還是因項目和環境而異吧。這里的路由用到了懶加載路由的方式,如果不清楚,文字上面有介紹到。還有meta元字段中,定義了一個title信息,用來存儲當前頁面的頁面標題,即document.title。
可選鏈操作符
js可選鏈操作“.?”雙問號“??”(babel-plugin-proposal-optional-chainingplugin-proposal-nullish-coalescing-operator)
可選鏈操作符 “?.” 可以按照操作符之前的屬性是否有效,鏈式讀取對象的屬性或者使整個對象鏈返回 undefined。“?.” 運算符的作用與“.”運算符類似,不同之處在于,如果對象鏈上的引用是 nullish (null 或者 undefined),“.” 操作符會拋出一個錯誤,而“ ?. ”操作符則會按照短路計算的方式進行處理,返回 undefined。可選鏈操作符也可用于函數調用,如果操作符前的函數不存在,也將會返回 undefined。
上面是官方解釋,假設你是第一次看到類似下面這類語法,大概你是懵逼的。
上面的代碼很容易產生錯誤,你大概會這么取值
插件安裝
基本語法(可選鏈)
obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)
短路:遇到 null/undefined 停止
可選鏈接運算符的有趣之處在于,只要在左側person?.details 遇到無效值,右側訪問就會停止,通常會返回undefined ,這稱為短路。
默認值(雙問號)
這個運算符就是“??”,如果它左側表達式的結果是 undefined,personData,就會取右側的"默認值"(stranger)。是不是跟運算符“||” 很像,其實“??” 就是為了取代“||” ,來做設置默認值這件事的。
兼容性
盡管這個特性很完美,但想直接在項目中使用還是不太現實的,好在還有babel,插件babel-plugin-proposal-optional-chaining、plugin-proposal-nullish-coalescing-operator
本地開發環境請求服務器接口跨域的問題
vue中判斷我們寫的組件名是不是html內置標簽的時候,如果用數組類遍歷那么將要循環很多次獲取結果,如果把數組轉為對象,把標簽名設置為對象的key,那么不用依次遍歷查找,只需要查找一次就能獲取結果,提高了查找效率。
END
作者簡介
蔡巍巍
2019年12月加入中國移動云能力中心,Iaas產品部云管中臺組組員,主要負責云管中臺前端相關研發、管理工作。
?往期 · 精選?
1、干貨分享 | 服務注冊中心Spring Cloud Eureka部分源碼分析
2、干貨分享 | 深入淺出基于Kpatch的內核熱補丁技術
3、干貨分享 | BRAFT快速上手-實踐篇
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的vs code vue插件_干货分享 | Vue框架常见问题浅谈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c#分页_使用Kotlin搭配Sprin
- 下一篇: lda 可以处理中文_用python处理