- 路由懒加载
当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
结合 Vue 的 异步组件 和 Webpack 的 code splitting feature, 轻松实现路由组件的懒加载。
我们要做的就是把路由对应的组件定义成异步组件:
const Foo = resolve => { // require.ensure 是 Webpack 的特殊语法,用来设置 code-split point // (代码分块)
require.ensure(['./Foo.vue'], () => { resolve(require('./Foo.vue')) })}
这里还有另一种代码分块的语法,使用 AMD 风格的 require,于是就更简单了:
const Foo = resolve => require(['./Foo.vue'], resolve)
不需要改变任何路由配置,跟之前一样使用
Foo:const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ]})
把组件按组分块
有时候我们想把某个路由下的所有组件都打包在同个异步 chunk 中。只需要 给 chunk 命名,提供 require.ensure
第三个参数作为 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 下的所有异步模块打包到一个异步块里面 —— 这也意味着我们无须明确列出 require.ensure
的依赖(传空数组就行)。
使用案例
- 有路由
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跳转页面
this.$router.push({
path: `/rank/${item.id}`
})
实际是跳转到TopList页面
this.$router.push({
path: `/recommend/${item.dissid}`
})
router-link页面跳转
<router-link tag="div" class="mine" to="/user">
<i class="icon-mine"></i>
</router-link>
返回
back() {
this.$router.back()
},
- 没有子路由
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
//webpack按需加载组件
//个性推荐
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'
})