路由懶加載指的是打包部署時將資源按照對應(yīng)的頁面進(jìn)行劃分,需要的時候加載對應(yīng)的頁面資源,而不是把所有的頁面資源打包部署到一塊。避免不必要資源加載。(參考vue項目實現(xiàn)路由按需加載(路由懶加載)的3種方式_小胖梅的博客-CSDN博客_vue懶加載?)
// 非懶加載
import Home from '@/components/Home'
const routes = [
{
path: '/home',
name: 'home',
component: Home
}
]
這里有三種方式可以實現(xiàn)vue項目路由跳轉(zhuǎn)時資源的按需加載。
1. vue異步組件
? vue-router配置路由,使用vue的異步組件技術(shù),可以實現(xiàn)按需加載。
? 但是,這種情況下每一個組件就會生成一個js文件,不能分類指定chunkName
// vue異步組件
{
path: '/home',
name: 'home',
component: resolve => require(['@/components/home'], resolve)
}
2. 使用import
// const 組件名 = () => import('組件路徑');
// 下面2行代碼,沒有指定webpackChunkName,每個組件打包成一個js文件。
const Home = () => import('@/componnets/home');
const Index = () => import('@/components/index');
// 下面2行代碼,指定了相同的webpackChunkName,會合并打包成一個js文件
// 把組件按組分塊
const Home = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/home');
const Index = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/index')
{
path: '/home',
name: 'home',
component: Home
}, {
path: '/index',
name: 'index',
component: Index
}
3. webpack提供的require.ensure()
? 該方法也可指定相同的chunkName,合并打包成一個js文件。
{
path: '/home',
name: 'home',
component: r => require.ensure([], () => r(require('@/components/home')), 'demo')
}, {
path: '/index',
name: 'index',
component: r => require.ensure([], () => r(require('@/components/index')), 'demo')
}, {
path: '/about',
name: 'about',
// 傳入空字符串 則每個component會單獨生成一個js文件
component: r => require.ensure([], () => r(require('@/components/index')), '')
}
公司后臺項目路由懶加載模式修改(新后臺vue2.0)
項目背景:老后臺(angular1.x版本)正在遷移新后臺(vue2.0)
未修改之前:
打完包之后有156個js文件,這是按照每個路由對應(yīng)的component生成一個js文件,這就意味著到時候老后臺全部遷移到新后臺之后,目前大概有800個路由,那就會生成800多個js文件,這種模式的路由懶加載對于后臺管理系統(tǒng)其實是沒有必要的,所以考慮通過webpackChunkName將各個模塊分類,一個一級分類指定一個chunkName。
修改之后:
打完包只有25個js文件,看起來就舒服多了。
各個大模塊路由懶加載修改的格式如下:
在一個大的路由模塊下,指定相同的webpackChunkName。
修改之后打包生成的文件名格式如下:
hash值之前為自己設(shè)置的webpackChunkName名稱。
這里當(dāng)時遇到的一個問題如下圖所示:
如左邊紅框所示,生成的文件里面多了一個用 '~' 拼接起來的js文件。
這個后來翻到了webpack的splitChunks.automaticNameDelimiter。因為項目中在這三個模塊下,都引入了同一個文件(UEditor),并且項目中也并沒有指定對應(yīng)的webpackChunkName,所以webpack內(nèi)部自動處理,將這個文件單獨提取出來,并自動命名,命名規(guī)則見webpack官方文檔,連接符 '~' 是可配置的。
出現(xiàn)? '~' 連接符的組件引入方式如下:
修改之后的引入方式如下:
指定了webpackChunkName,以后其他模塊引入富文本UEditor時也請按照此方式引入,命名保持相同。
以下是webpack官方文檔對automaticNameDelimiter配置的解釋。
vue-router核心原理解析:(參考【第2194期】SPA 路由三部曲之核心原理?)
路由描述了URL和UI之間的映射關(guān)系,這種映射是單向的,即URL變化引起UI更新(無需刷新頁面)。前端路由最主要的展示方式有2種:
- 帶有hash的前端路由:地址欄URL中有 #,即hash值,不好看,但兼容性高。
- 不帶hash的前端路由:地址欄URL中沒有 #,好看,但部分瀏覽器不支持,還需要后端服務(wù)器支持。
在vue-router中,這兩種展示形式,被定義成兩種模式,即Hash模式與History模式。前端路由實現(xiàn)原理很簡單,本質(zhì)上就是檢測URL的變化,截獲URL地址,通過解析、匹配路由規(guī)則實現(xiàn)UI更新。
① Hash模式
一個完整的URL包括:協(xié)議、域名、端口、虛擬目錄、文件名、參數(shù)、錨。
Hash值指的是URL地址中的錨部分,也就是# 后面的部分。hash也稱作錨點,是用來做頁面定位的,與hash值對應(yīng)的DOM id顯示在可視區(qū)域內(nèi)。在HTML5的history新特性出現(xiàn)前,基本都是使用監(jiān)聽hash值來實現(xiàn)前端路由的。hash值更新有一下幾個特點:
- hash值是網(wǎng)頁的標(biāo)志位,HTTP請求不包含錨部分,對后端無影響
- 因為HTTP請求不包含錨部分,所以hash值改變時,不觸發(fā)網(wǎng)頁重載
- 改變hash值會改變?yōu)g覽器的歷史紀(jì)錄
- 改變hash值會觸發(fā)window.onhashchange()事件
而改變hash值的方式有3種:
- a標(biāo)簽使錨點值變化,例:<a href="#/home"></a>
- 通過設(shè)置window.location.hash的值
- 瀏覽器前進(jìn)鍵(history.forword())、后退鍵(history.back())
綜上所述,這3種改變hash值的方式,并不會導(dǎo)致瀏覽器向服務(wù)器發(fā)送請求,瀏覽器不發(fā)出請求,也就不會刷新頁面。hash值改變,觸發(fā)全局的window對象上的hashchange事件。所以hash模式路由就是利用hashchange事件監(jiān)聽URL的變化,從而進(jìn)行DOM操作來模擬頁面跳轉(zhuǎn)。
② History模式
主要應(yīng)用了History API新增的兩個方法:pushState()、replaceState(),均具有操縱瀏覽器歷史記錄的能力。
history.pushState(state, title, URL),該方法共接收3個參數(shù):
- state:用于存儲該URL對應(yīng)的狀態(tài)對象,可以通過history.state獲取
- title:標(biāo)題,目前瀏覽器并不支持
- URL:定義新的歷史URL記錄,需要注意,新的URL必須與當(dāng)前URL同源,不能跨域
pushState函數(shù)會向瀏覽器的歷史記錄中國添加一條,history.length的值會+1,當(dāng)前瀏覽器的URL變成了新的URL。需要注意的是:僅僅將瀏覽器的URL變成了新的URL,頁面不會加載、刷新。
history.replaceState(state, title, URL)
replaceState的使用與pushState非常相似,都是改變當(dāng)前的URL,頁面不刷新。區(qū)別在于replaceState是修改了當(dāng)前的歷史記錄項而不是新建一個,history.length的值保持不變。
window.onpopstate()
為了配合history.pushState()或者h(yuǎn)istory.replaceState(),HTML5還新增了一個事件,用于監(jiān)聽URL歷史記錄改變:window.onpopstate。
官方對于window.onpopstate()事件的描述是這樣的:
每當(dāng)處于激活狀態(tài)的歷史記錄條目發(fā)生變化時,popstate事件就會在對應(yīng)的window對象上觸發(fā)。如果當(dāng)前處于激活狀態(tài)的歷史記錄條目是由history.pushState()方法創(chuàng)建,或者由history.replaceState()方法修改過的,則popstate事件對象的state屬性包含了這個歷史記錄條目的state對象的一個拷貝。調(diào)用history.pushState()或者h(yuǎn)istory.replaceState()不會觸發(fā)popstate事件。popstate事件只會在瀏覽器某些行為下觸發(fā),比如點擊后退、前進(jìn)按鈕(或者在Javascript中調(diào)用 history.back()、history.foward()、history.go()方法),此外,a標(biāo)簽的錨點也會觸發(fā)該事件。文章來源:http://www.zghlxwxcb.cn/news/detail-402300.html
結(jié)合上述,在瀏覽器支持 pushState 的情況下,hash 模式路由也可以使用 pushState 、replaceState 和 popstate 實現(xiàn)。pushstate 改變 hash 值,進(jìn)行跳轉(zhuǎn),popstate 監(jiān)聽 hash 值的變化。小小的劇透,vue-router 中不管是 hash 模式,還是 history 模式,只要瀏覽器支持 history 的新特性,使用的都是 history 的新特性進(jìn)行跳轉(zhuǎn)。文章來源地址http://www.zghlxwxcb.cn/news/detail-402300.html
到了這里,關(guān)于vue-router路由懶加載的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!