Vue.js之vue-router
HTML
<div id="app"> <h1>Hello App!</h1> <p> <!-- 使用 router-link 组件来导航. --> <!-- 通过传入 `to` 属性指定链接. --> <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 --> <router-link to="/foo">Go to Foo</router-link> <router-link to="/bar">Go to Bar</router-link> </p> <!-- 路由出口 --> <!-- 路由匹配到的组件将渲染在这里 --> <router-view></router-view> </div>
JavaScript
1.引入vue,vue-router
import Vue from 'vue' import VueRouter from 'vue-router'
2.引入路由配置文件
import routerConfig from './router.config.js'
3.使用路由
Vue.use(VueRouter);
4.创建router实例,然后传入`routes`配置routerConfig
const router=new VueRouter({ routes:routerConfig //相当于 routes: routerConfig })
5.创建和挂载根实例
记得要通过 router 配置参数注入路由,从而让整个应用都有路由功能
new Vue({ router, el:'#app' })
router.config.js 定义路由文件
1.引入组件
import Home from ‘/component/Home.vue’ import News from ‘/component/News .vue’
2.导出定义的路由
//格式为数组包含json对象
export default[ {path:'/home',component:Home}, {path:'/News ',component:News } ]
监听路由变化watch
export default { watch:{ $route(){ alert(1) } } }
要把vue-router引入进来,我们需要做的是,将组件映射到路由,然后告诉路由在哪里渲染组件内容。
动态路由
动态路由其实又可以叫做路由传参。
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})
上述形式的路径即为动态路由,冒号后是参数,可以跟多段参数,每个参数都被设置到this.$route.params中。
注意/user/:id和/user/:name,当参数变化时,组件会被复用,因此组件生命周期钩子不会被再次调用。复用组建时,可以通过监听$route对象的变化来监测路由是否变化。
路由钩子beforeRouterUpdate也会执行。
懒加载
当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
异步组件模式:
const Foo = resolve => {
// require.ensure 是 Webpack 的特殊语法,用来设置 code-split point
// (代码分块)
require.ensure(['./Foo.vue'], () => {
resolve(require('./Foo.vue'))
})
}
Amd风格的require模式:
const routes = [
{
path: '',
component: resolve => require(['./index.vue'],resolve),
}, {
path: '/user',
component: resolve => require(['./user.vue'],resolve),
}];
导航钩子
vue-router中的导航钩子按定义位置不同(执行时机也不同)分为全局钩子、路由级钩子和组件级钩子。
- 全局钩子
全局钩子有三个,分别是beforeEach、beforeResolve和afterEach,在路由实例对象注册使用;
- 路由级钩子
路由级钩子有beforeEnter,在路由配置项中项定义;
- 组件级钩子
组件级钩子有beforeRouteEnter、beforeRouteUpdate和beforeRouteLeave,在组件属性中定义;
2. 代码示例
import Vue from 'vue';
import VueRouter from 'vue-router';
// Vue中插件必须use注册
Vue.use(VueRouter);
// 路由配置项,此处是路由级钩子的定义
const routes = [{
path: '/',
component: resolve => require(['./index.vue'], resolve),
keepAlive: true,
},
{
path: '/user/:userName',
keepAlive: true,
beforeEnter(to,from,next){
console.log('router beforeEnter');
next();
},
component: resolve => require(['./user.vue'], resolve),
}];
// 实例化路由对象
const router = new VueRouter({
routes
});
// 全局钩子
router.beforeEach((to,from,next)=>{
console.log('global beforeEach')
next();
});
router.beforeResolve((to,from,next)=>{
console.log('global beforeResolve')
next();
});
router.afterEach((to,from,next)=>{
console.log('global afterEach')
});
// 实例化Vue对象并挂载
new Vue({
router
}).$mount('#app');
user.vue
<template> <div> <h1>{{ msg }}</h1> <p>我是:{{userName}}</p> </div> </template> <script> export default { name: 'user', data () { return { msg: '这里是 User Page.', userName: '叶落' }; }, methods: {}, mounted () { var me = this; me.userName = me.$route.params.userName; console.log('user mounted.'); }, beforeRouteEnter (to, from, next) { console.log('component beforeRouteEnter'); next(); }, beforeRouteUpdate (to, from, next) { console.log('component beforeRouteUpdate'); next(); }, beforeRouteLeave(to,from,next){ console.log('component beforeRouteLeave'); next(); } }; </script>