- 路由懶加載
當(dāng)打包構(gòu)建應(yīng)用時(shí),Javascript 包會(huì)變得非常大,影響頁(yè)面加載。如果我們能把不同路由對(duì)應(yīng)的組件分割成不同的代碼塊,然后當(dāng)路由被訪問(wèn)的時(shí)候才加載對(duì)應(yīng)組件,這樣就更加高效了。
結(jié)合 Vue 的 異步組件 和 Webpack 的 code splitting feature, 輕松實(shí)現(xiàn)路由組件的懶加載。
我們要做的就是把路由對(duì)應(yīng)的組件定義成異步組件:
const Foo = resolve => { // require.ensure 是 Webpack 的特殊語(yǔ)法,用來(lái)設(shè)置 code-split point // (代碼分塊)
require.ensure(['./Foo.vue'], () => { resolve(require('./Foo.vue')) })}
這里還有另一種代碼分塊的語(yǔ)法,使用 AMD 風(fēng)格的 require,于是就更簡(jiǎn)單了:
const Foo = resolve => require(['./Foo.vue'], resolve)
不需要改變?nèi)魏温酚膳渲茫耙粯邮褂?/p>
Foo:const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ]})
把組件按組分塊
有時(shí)候我們想把某個(gè)路由下的所有組件都打包在同個(gè)異步 chunk 中。只需要 給 chunk 命名,提供 require.ensure
第三個(gè)參數(shù)作為 chunk 的名稱:
const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo')
const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo')
const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo')
Webpack 將相同 chunk 下的所有異步模塊打包到一個(gè)異步塊里面 —— 這也意味著我們無(wú)須明確列出 require.ensure
的依賴(傳空數(shù)組就行)。
使用案例
- 有路由
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const Recommend = (resolve) => {
import('components/recommend/recommend').then((module) => {
resolve(module)
})
}
const Singer = (resolve) => {
import('components/singer/singer').then((module) => {
resolve(module)
})
}
const Rank = (resolve) => {
import('components/rank/rank').then((module) => {
resolve(module)
})
}
const Search = (resolve) => {
import('components/search/search').then((module) => {
resolve(module)
})
}
const SingerDetail = (resolve) => {
import('components/singer-detail/singer-detail').then((module) => {
resolve(module)
})
}
const Disc = (resolve) => {
import('components/disc/disc').then((module) => {
resolve(module)
})
}
const TopList = (resolve) => {
import('components/top-list/top-list').then((module) => {
resolve(module)
})
}
const UserCenter = (resolve) => {
import('components/user-center/user-center').then((module) => {
resolve(module)
})
}
export default new Router({
routes: [
{
path: '/',
redirect: '/recommend'
},
{
path: '/recommend',
component: Recommend,
children: [
{
path: ':id',
component: Disc
}
]
},
{
path: '/singer',
component: Singer,
children: [
{
path: ':id',
component: SingerDetail
}
]
},
{
path: '/rank',
component: Rank,
children: [
{
path: ':id',
component: TopList
}
]
},
{
path: '/search',
component: Search,
children: [
{
path: ':id',
component: SingerDetail
}
]
},
{
path: '/user',
component: UserCenter
}
]
})
js跳轉(zhuǎn)頁(yè)面
this.$router.push({
path: `/rank/${item.id}`
})
實(shí)際是跳轉(zhuǎn)到TopList頁(yè)面
this.$router.push({
path: `/recommend/${item.dissid}`
})
router-link頁(yè)面跳轉(zhuǎn)
<router-link tag="div" class="mine" to="/user">
<i class="icon-mine"></i>
</router-link>
返回
back() {
this.$router.back()
},
- 沒(méi)有子路由
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
//webpack按需加載組件
//個(gè)性推薦
const recommend = r => require.ensure([], () => r(require('../page/recommend/recommend')), ' recommend')
//歌單詳情
const songListDetails = r => require.ensure([], () => r(require('../page/songListDetails/songListDetails')), 'songListDetails')
//歌曲詳情
const songDetails = r => require.ensure([], () => r(require('../page/songDetails/songDetails')), 'songDetails')
//精品歌單
const songList = r => require.ensure([], () => r(require('../page/songList/songList')), 'songList')
//排行榜
const topList = r => require.ensure([], () => r(require('../page/topList/topList')), 'topList')
//搜索列表
const searchList = r => require.ensure([], () => r(require('../page/searchList/searchList')), 'searchList')
//獲取歌手歌單
const singer = r => require.ensure([], () => r(require('../page/singer/singer')), 'singer')
//專輯詳情
const albumsListDetails = r => require.ensure([], () => r(require('../page/albumsListDetails/albumsListDetails')), 'albumsListDetails')
export default new Router({
routes: [{
path: '/',
redirect: '/recommend'
},
{
path: '/recommend',
name: 'recommend',
component: recommend
}, {
path: '/songListDetails/:id',
name: 'songListDetails',
component: songListDetails
}, {
path: '/songDetails/:id',
name: 'songDetails',
component: songDetails
},
{
path: '/songList',
name: 'songList',
component: songList
}, {
path: '/topList',
name: 'topList',
component: topList
}, {
path: '/searchList',
name: 'searchList',
component: searchList
}, {
path: '/singer/:id',
name: 'singer',
component: singer
},
{
path: '/albumsListDetails/:id',
name: 'albumsListDetails',
component: albumsListDetails
}
],
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return {
x: 0,
y: 0
}
}
}
})
//router-link
<ul>
<router-link v-for="(item,i) in PrSongList" :key="i" tag="li" :to="{name:'songListDetails',params:{id:item.id}}">
<i class="iconfont icon-headset">{{format.formatPlayCount(item.playCount)}}</i>
<img v-lazy="item.picUrl">
<p>{{item.name}}</p>
</router-link>
</ul>
this.$route.params.id
this.$router.go(-1);
this.$router.push({
name: 'songList'
})