vue router
参考:
https://router.vuejs.org/zh-cn/advanced/lazy-loading.html
路由懒加载
// 配置文件 module.exports = { entry: { index: './index.js', }, output: { path: __dirname + "/dist", filename: "[name].js", publicPath:"./dist/" }, devtool: 'eval-source-map', module: { rules: [ { test: /\.vue$/, loader: 'vue-loader' }, { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader", options: { presets: ["es2015"], plugins: ["syntax-dynamic-import"] } }, exclude: /node_modules/ } ] }, resolve: { extensions: [".vue",".js",".json"], alias: { 'vue$': 'vue/dist/vue.js', } } }; // ./routers/uA.vue <template> <div> aaaaaaaaaaa </div> </template> <script> export default { name: "v-a" } </script> <style scoped></style> // ./routers/uB.vue <template> <div> bbbbbbbbbbb </div> </template> <script> export default { name: "v-b" } </script> <style scoped></style> // index.js import VueRouter from "vue-router" import Vue from "vue" const vA = ()=> import('./routers/vA') const vB = ()=> import('./routers/vB') const router = new VueRouter({ routes: [ { path: '/a', component: vA }, { path: '/b', component: vB } ] }) Vue.use(VueRouter) new Vue({ el:"#root", router:router }); // main.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="root"> <router-link to="/a">Go to a</router-link> <router-link to="/b">Go to b</router-link> <router-view></router-view> </div> </body> <script src="dist/index.js"></script> </html> // 依赖 "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-preset-es2015": "^6.24.1", "css-loader": "^0.28.8", "style-loader": "^0.19.1", "vue": "^2.5.13", "vue-loader": "^13.6.2", "vue-router": "^3.0.1", "vue-template-compiler": "^2.5.13", "webpack": "^3.10.0" }
仅当这个路由组件第一次需要被显示的时候,才会下载这个组件。打包后dist出现这几个文件:
0和1代表被异步加载的路由组件。
如果手误,import一个vue-loader,则会报如下错误:
WARNING in ./node_modules/vue-loader/lib/utils/try-require.js
12:11-27 Critical dependency: the request of a dependency is an expression
@ ./node_modules/vue-loader/lib/utils/try-require.js
@ ./node_modules/vue-loader/lib/loader.js
@ ./node_modules/vue-loader/index.js
@ ./index.js
ERROR in ./node_modules/resolve/lib/async.js
Module not found: Error: Can't resolve 'fs' in 'C:\Users\MRLWJ\Desktop\test\router\node_modules\resolve\lib'
@ ./node_modules/resolve/lib/async.js 2:9-22
@ ./node_modules/resolve/index.js
@ ./node_modules/vue-loader/lib/utils/try-require.js
@ ./node_modules/vue-loader/lib/loader.js
@ ./node_modules/vue-loader/index.js
@ ./index.js
Api
关于路由守卫:https://router.vuejs.org/zh-cn/advanced/navigation-guards.html
this.$router.push('/qwe'):
修改路由为 #/qwe(路由组件会切换),不发出请求
router.onReady
回调函数被调用的时候,就意味着当前要显示的(同步或者异步)路由组件已经准备好了,这时这个路由组件还没有完成挂载(onReady的回调函数在组件beforeCreate前执行)。
router.beforeEach
在路由切换前执行(页面打开时也会执行一次),回调函数中需要调用next(),否则路由不切换。可以注册多个,会按次序执行,上一个没有执行next的话,下一个不会执行,路由不会切换,当最后一个执行了next时,路由才开始切换(组件开始挂载)
文档中提示的触发流程如下:
- Navigation triggered.
- Call leave guards in deactivated components.
- Call global
beforeEach
guards. - Call
beforeRouteUpdate
guards in reused components (2.2+). - Call
beforeEnter
in route configs. - Resolve async route components.
- Call
beforeRouteEnter
in activated components. - Call global
beforeResolve
guards (2.5+). - Navigation confirmed.
- Call global
afterEach
hooks. - DOM updates triggered.
- Call callbacks passed to
next
inbeforeRouteEnter
guards with instantiated instances.
以上流程中,只要next没执行,就不会到下一步,如进行以下设置:
beforeRouteEnter(to,form,next){ setTimeout(()=>{ next() },2000) }
则全局的beforeResolve会等待以上的next执行后执行。
切换路由,组件由A->B时:
在路由中,component reused 的意思是路由没有发生变化,而仅仅参数发生了变化(user/1 -> user/2),这时组件中的钩子 beforeRouteUpdate会执行。