之前的文章《淺析vue中complie數(shù)據(jù)雙向綁定原理(代碼詳解)》中,給大家了解了vue中complie數(shù)據(jù)雙向綁定原理。下面本篇文章給大家了解vue中路由切換白屏的問(wèn)題,伙伴們來(lái)看看。
關(guān)于vue
路由切換的白屏,事實(shí)上在開(kāi)發(fā)的過(guò)程中,我一直沒(méi)有遇到過(guò)。
我有個(gè)哥們遇到這個(gè)問(wèn)題,問(wèn)我怎么解決的,我暈了,我沒(méi)遇到這樣的問(wèn)題啊,我怎么解決啊啊啊啊。。
事實(shí)上是遇到過(guò)一回的。
以下內(nèi)容于 2019-07-25 修改。
服務(wù)器部署配置問(wèn)題
這個(gè)問(wèn)題造成的白屏體現(xiàn)在:
首頁(yè)可以正常瀏覽,但是——通過(guò)$router.push('/home')
跳轉(zhuǎn)頁(yè)面 正常,然后刷新就是白屏或 404
本不想在文章加入這個(gè)問(wèn)題和解決方案,因?yàn)楣倬W(wǎng)已經(jīng)提供了正確的部署姿勢(shì),(Vue
的路由模式自行查看文檔),主要是針對(duì)HTML5 History
模式:
const router = new VueRouter({ mode: 'history', routes: [...] })
dev
和build
都沒(méi)有問(wèn)題,這個(gè)是肯定的,所以問(wèn)題就出在服務(wù)器配置上,以nginx
為例,正確的配置如下:
location / { .... try_files $uri $uri/ /index.html; #重點(diǎn) }
Apache
,原生 Node.js
,IIS
,Caddy
,Firebase
主機(jī)
請(qǐng)查看
vur-router
后端配置例子地址:https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90
以上內(nèi)容于 2019-07-25 修改。
以下內(nèi)容于 2019-04-23 修改。
如果你是使用腳手架初始化環(huán)境,可以跳過(guò)這部分。如果自己配置webpack
,可以接著看確定做了如下配置
devServer: { ... contentBase: false, //必須 historyApiFallback: true, //必須 ... }, entry: { app: ['./src/main.js'], vendors: ['vue', 'vue-router'] //注意這里 }, plugins: [ .... new HtmlWebpackPlugin({ ... chunks: ['vendors', 'app'], //注意這里,這里的chunks 要包含入口的 entry }) ]
以上內(nèi)容于2019-04-23修改。
場(chǎng)景一:IE9(兼容性問(wèn)題)
嚴(yán)格來(lái)說(shuō)不是白屏的問(wèn)題,應(yīng)該說(shuō)是兼容性問(wèn)題,直接就是不支持,報(bào)錯(cuò)了,渲染無(wú)法執(zhí)行造成的。解決方式就是
npm i babel-polyfill -D
然后在入口mian.js引入就完事了,就著么簡(jiǎn)單
import "babel-polyfill";
或者
//webpack entry: { app: ['babel-polyfill','./src/main.js'], vendors: ['vue', 'vue-router'] },
以下內(nèi)容于2019-04-23修改。
假如真的是js
兼容性問(wèn)題,那么真的只是引入babel-polyfill
或者在webpack
入口加入babel-polyfill
問(wèn)題就能解決嗎,其實(shí)不一定的,這個(gè)要看項(xiàng)目的使用情況。babel-polyfill
不是萬(wàn)能的。那么如何排查兼容性問(wèn)題呢(假如真的是兼容性問(wèn)題)。因?yàn)槲覀冊(cè)谑謾C(jī)上直接調(diào)試,有些錯(cuò)誤不會(huì)那么容易顯而易見(jiàn)。我是這么調(diào)試的。(僅供參考?。?/p>
<template> <div> <!-- 錯(cuò)誤直接顯示在這里. 不用 alert() ,console.log() --> {{error}} ... <!-- other element --> </div> </template> <script> export default{ data{ return { error:'' } }, moundted:{ try{ //一些請(qǐng)求數(shù)據(jù)的方法 }catch(e){ //這里拋出異常 this.error = e } } } </script>
這里要說(shuō)的是有些兼容性問(wèn)題是bable-polyfill
搞不定的。比如URLSearchParams
let data = new URLSearchParams(); for (var key in params) { data.append(key, params[key]); }
那么肯定會(huì)報(bào)URLSearchParams is not undefined
,然后,錯(cuò)誤只在一些低端的機(jī)型,一些偶然的場(chǎng)合出錯(cuò).加大了錯(cuò)誤的排查。
以下可以解決URLSearchParams is not undefined
//# console npm i url-search-params-polyfill //# mian.js import 'url-search-params-polyfill';
以上內(nèi)容于2019-04-23修改。
場(chǎng)景二 :如下圖
有人說(shuō)是在iphone 5s或者6s上會(huì)出現(xiàn)這種問(wèn)題,肯定不是手機(jī)的bug。于是我重現(xiàn)了場(chǎng)景,真的和設(shè)備無(wú)關(guān)
所以這個(gè)跟設(shè)備真的沒(méi)有關(guān)系。知道問(wèn)題所在,當(dāng)然解決辦法也有許多
方案一:暴力愚蠢型
//路由跳轉(zhuǎn)前滾動(dòng)條清零 document.body.scrollTop = document.documentElement.scrollTop = 0; this.$router.push({ path: "/a/b/c" });
方案二:可行但不可選型
//給router 加一個(gè)監(jiān)聽(tīng),一旦改變,執(zhí)行清零,然后再跳轉(zhuǎn) let routers = new Router({.....}) routers.beforeEach(function (to, from, next) { ...... document.body.scrollTop = document.documentElement.scrollTop = 0 next() })
雖然可行,但是感覺(jué)著么干有點(diǎn)愚蠢。因?yàn)檫€有更好的寫法,這個(gè)寫法更佳優(yōu)雅
方案三:最佳型
其實(shí)官方已經(jīng)提供了當(dāng)路由切換時(shí),控制滾動(dòng)位置的方式。scrollBehavior
使用方式如下:
const router = new VueRouter({ routes: [...], scrollBehavior (to, from, savedPosition) { // return 期望滾動(dòng)到哪個(gè)的位置 { x: number, y: number } | { selector: string } | } })
scrollBehavior
方法接收to
和from
路由對(duì)象。第三個(gè)參數(shù)savedPosition
當(dāng)且僅當(dāng)popstate
導(dǎo)航(通過(guò)瀏覽器的前進(jìn)/后退按鈕觸發(fā)) 時(shí)才可用。
所以假如要解決白屏的問(wèn)題,可以著么干
const router = new VueRouter({ routes: [...], scrollBehavior (to, from, savedPosition) { return savedPosition || { x: 0, y: 0 } } })
也就是說(shuō),當(dāng)用戶點(diǎn)擊返回、前進(jìn)的時(shí)候,頁(yè)面會(huì)滾動(dòng)到之前位置,(微信朋友圈的文章就是這樣的,讀一半返回,再進(jìn)來(lái)接著剛才的位置閱讀)
如果是新的page
被mounted
進(jìn)來(lái)的時(shí)候,就重置為 0
。
完美的解決了這個(gè)問(wèn)題。
但是這也是個(gè)問(wèn)題,框架為什么不默認(rèn)呢,假如自定義的時(shí)候可以overwirte
。
場(chǎng)景三: 緩存的原因(2019.4.15)
我們根據(jù)版本號(hào)(或者hash
)去控制緩存問(wèn)題,當(dāng)我們發(fā)布新版本,會(huì)發(fā)現(xiàn)html里面引用的版本號(hào)卻是舊的版本號(hào) ,這種情況是入口index.html
文件被緩存了,很多時(shí)候我們?cè)O(shè)置禁止html
文件被緩存,但依然會(huì)出現(xiàn)被緩存的情況。比如在頭部加
<meta http-equiv="Expires" content="0" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Cache-control" content="no-cache" /> <meta http-equiv="Cache" content="no-cache" />
仍然解決不了問(wèn)題,關(guān)于web
的緩存策略,推薦這篇文章:Http緩存機(jī)制
一旦index.html
被緩存了,之后我們使用了全量更新,也就是每次發(fā)版本之前會(huì)干掉之前的js
和css
文件,那么被緩存的index.html
會(huì)無(wú)法加載之前舊的js,css
還有一些其他的靜態(tài)資源文件,而新的js
和css
則不會(huì)被加載,那么白屏就誕生了。
這個(gè)時(shí)候我們就要配合服務(wù)端來(lái)解決index.html
的緩存問(wèn)題
解決緩存的問(wèn)題請(qǐng)轉(zhuǎn)到這里:Vue index.html入口緩存問(wèn)題
[完]
推薦學(xué)習(xí):vue.js教程