vue-router

首先抛出这样一个问题,vue-router是用来做什么的?

这里不着急回答,也不准备在这篇文章里回答。这篇文章仅总结一些使用心得,其实总结完所有关于vue-router的内容后,整篇文章也许就刚好能回答这个问题了。

一 使用步骤

单纯使用Vue.js,我们可以通过组合组件来组成应用,不同的页面有不同的地址,路由依靠链接跳转。这显然不是单页应用,因为会有页面刷新。

当要把vue-router引入进来,我们需要做的是,将组件映射到路由,然后告诉路由在哪里渲染组件内容。

1. HTML

vue-router

Hello World!


toUser


2. JavaScript

importVuefrom'vue';

importVueRouterfrom'vue-router';

importindexPagefrom'./index.vue';

importuserPagefrom'./user.vue';

// 注册路由插件

Vue.use(VueRouter);

// 配置路由

constroutes=[

{

path:'',

component:indexPage,

},{

path:'/user',

component:userPage,

}];

// 创建Router实例

constrouter=newVueRouter({

routes,

});

// 创建和挂载Vue根实例

constapp=newVue({

router,

});

app.$mount('#app');

router-link和router-view是两个功能性内置组件。router-link默认被渲染为a标签,负责路由跳转功能;router-view是组件内容被渲染的位置。

js方面代码里的注释已经写得很清楚。

二 动态路由

动态路由其实又可以叫做路由传参。

constrouter=newVueRouter({

routes:[

// 动态路径参数 以冒号开头

{path:'/user/:id',component:User}

]

})

形如上述形式的路径即为动态路由,冒号后是参数,可以跟多段参数,每个参数都被设置到this.$route.params中。

注意/user/:id和/user/:name,当参数变化时,组件会被复用,因此组件生命周期钩子不会被再次调用。复用组建时,可以通过监听$route对象的变化来监测路由是否变化。

路由钩子beforeRouterUpdate也会执行。

vue-router 使用path-to-regexp作为路径匹配引擎,假如路径很复杂可以学习高级的匹配模式。但是路径一般不应设计的太复杂,如果太复杂,应该考虑如何简化。

三 命名视图

有时候想同时(同级)展示多个视图,例如创建一个布局,有 sidebar(侧导航) 和 main(主内容)

两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view

没有设置名字,那么默认为 default。

一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置(带上 s):

routes:[

{

path:'/',

components:{

default:Foo,

a:SideBar,

b:Header

}

}

]

四 路由元信息

定义路由的时候可以配置 meta 字段:

routes:[

{

path:'/foo',

component:Foo,

children:[

{

path:'bar',

component:Bar,

// a meta field

meta:{requiresAuth:true}

}

]

}

]

五 编程式导航

除了使用 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

router.push(location)

想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

当你点击 时,这个方法会在内部调用,所以说,点击 等同于调用 router.push(...)。

router.replace(location)

跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

router.go(n);

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。

六 懒加载

当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

异步组件模式:

constFoo=resolve =>{

// require.ensure 是 Webpack 的特殊语法,用来设置 code-split point

// (代码分块)

require.ensure(['./Foo.vue'],()=>{

resolve(require('./Foo.vue'))

})

}

Amd风格的require模式:

constroutes=[

{

path:'',

component:resolve =>require(['./index.vue'],resolve),

},{

path:'/user',

component:resolve =>require(['./user.vue'],resolve),

}];

ensure模式写起来有点繁琐,我更倾向于后面一种写法。

七 导航钩子

钩子(Hook),早期编程可能有个概念叫句柄,不知道将两者类比而且强行归为一类是不是合适。钩子的用处是在某个特定流程中的不同时机暴露出一些函数,使得用户可以通过覆写这些函数实现在原有位置执行自己的代码逻辑的功能。

1. 分类

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

   

       

{{ msg }}

       

我是:{{userName}}


    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();

        }

    };

3. 执行时机

由首页进入user页面:

global beforeEach > router beforeEnter > component

beforeRouteEnter > global beforeResolve > global afterEach >

mounted

由user回到首页:

component beforeRouteLeave => global beforeEach => global beforeResolve => global afterEach

排除beforeRouteUpdate,其余六个导航钩子的执行时机其实很好理解。大体按照leave、before、enter、resolve、after的顺序并全局优先的思路执行。beforeRouteUpdate的触发是在动态路由情形下,比如

path: '/user/:userName'

这条路由,当页面不变更只动态的改变参数userName时,beforeRouteUpdate便会触发。

总结:使用vue组件拼凑成整个应用,每个页面是独立的,路由依靠链接跳转,会刷新页面。使用vue-router则可以不刷新页面加载对应组件,hash和history模式模拟路径变化,不刷新页面。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容

  • xbm524阅读 282评论 0 1
  • 你好,回来了。看到肖女士走进小区大门,我打了声招呼。她挽着一个男人的手,用微笑表示回应。肖女士今天穿的是超短裙,真...
    野外一匹马阅读 2,719评论 0 5