摘要:Vue Router是Vue.js 官网的路由管理器。它和Vue.js的外围深度集成,能够十分不便的用于SPA应用程序的开发。

本文分享自华为云社区《Vue-Router路由疾速理解与利用》,原文作者:北极光之夜。

一.速识概念:

1. 后端路由:

1.依据不同的用户URL申请,返回不同的内容,实质上是URL申请地址与服务器资源之间的对应关系。

2.然而呢,后端渲染存在性能问题。

2. 前端路由:

3.所以呈现了Ajax前编渲染 ,前端渲染能进步性能,然而不反对浏览器的后退后退操作。

4.这时又呈现了SPA (Single Page Application)单页面应用程序,整个网站只有一个页面,内容的变动通过Ajax部分更新实现、同时反对浏览器地址栏的后退和后退操作。

5.SPA实现原理之一就是基于URL地址的 hash (hash的变动会导致浏览器记录拜访历史的变动、然而hash的变动不会触发新的URL申请) 。在实现SPA过程中, 其中最外围的技术点就是前端路由。

6.前端路由就是依据不同的用户事件,显示不同的页面内容。实质就是用户事件与事件处理函数之间的对应关系。

3.Vue Router:

这是官网应用文档链接。:https://router.vuejs.org/zh/g...

Vue Router是Vue.js 官网的路由管理器。它和Vue.js的外围深度集成,能够十分不便的用于SPA应用程序的开发。

它的性能如下:

1.反对HTML5历史模式或hash模式。
2.反对嵌套路由。
3.反对路由参数。
4.反对编程式路由。
5.反对命名路由。

二.根本应用:

前提:

上面将会以一个HTML单页面演示Vue Router的根本应用步骤。在vue我的项目里也是一样的原理。以后单页面根本代码:

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><body>    <div id="app">    </div>    <script>        const app = new Vue({            el:"#app",            data: {}        })    </script></body></html>

能够看到什么都没有:

上面开始应用的具体步骤:

1.引入相干的文件:

单页面必定得先导入vue文件与vue-router文件,这样咱们才可能应用路由。

<script src="https://unpkg.com/vue/dist/vue.js"></script><script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

2.增加路由链接:

以下是一个vue提供的标签,默认会被渲染为a标签。其中有一个to属性,这个to属性会被渲染为href属性,默认值被渲染为 # 结尾的hash地址。简略来说就是当用户点击不同时跳转不同内容,而这个标签就是用户要点击的货色,相当于a标签嘛。

<router-link to="/..." >...</router-link>

给咱们的单页面上加一个page1和一个page2的链接:

<div id="app">       <router-link to="/page1">Page1</router-link>       <router-link to="/page2">Page2</router-link>    </div>

3.增加路由填充位:

上面这个标签叫路由填充位,就是说将来通过咱们的路由规定匹配到的组件,将会被渲染到 router-view所在位置。简略来说,就是用户点击路由链接,那得跳转内容吧,咱们晓得的是必定不是整个页面都跳转,只是页面内相干的部分产生内容扭转,这个部分就是router-view所在显示的区域。

<router-view></router-view>
给咱们的页面增加:

<div id="app">        <router-link to="/page1">Page1</router-link>       <router-link to="/page2">Page2</router-link>       <router-view></router-view>    </div>

4.定义路由组件:

既然要显示不同的内容,那必定是用一个组件保留一份内容。上面咱们给单页面定义page1,page2这两个组件。

<script>        const Page1 = {            template: '<h1>我是北极光之夜1号</h1>'        }        const Page2 = {            template: '<h1>我是北极光之夜2号</h1>'        }        const app = new Vue({            el:"#app",            data: {}        })    </script>

5.配置路由规定井创立路由实例:

routes是路由规定数组。每个路由规定都是一个配置对象, 其中至多蕴含path 和component 两个属性,path 示意以后路由规定匹配的hash 地址,component 示意以后路由规定对应要展现的组件。简略来说就是你点击那个链接对应的地址要对应的是哪个内容的组件。path跟router-link标签里的地址要一样,别写错了。

const router = new VueRouter({            routes: [                {path:'/page1',component:Page1 },                {path:'/page2',component:Page2 }            ]        })

6.把路由挂载到Vue根实例中:

为了可能让路由规定失效,必须把路由对象挂载到vue 实例对象上。

const app = new Vue({            el:"#app",            data: {},            router        })

7.成果与单页面代码:

以上咱们就大工告成~

下面的残缺代码:

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title>    <!-- 导入vue文件 -->    <script src="https://unpkg.com/vue/dist/vue.js"></script>    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script></head><body>    <div id="app">       <router-link to="/page1">Page1</router-link>       <router-link to="/page2">Page2</router-link>       <router-view></router-view>    </div>    <script>        const Page1 = {            template: '<h1>我是北极光之夜1号</h1>'        }        const Page2 = {            template: '<h1>我是北极光之夜2号</h1>'        }        const router = new VueRouter({            routes: [                {path:'/page1',component:Page1 },                {path:'/page2',component:Page2 }            ]        })        const app = new Vue({            el:"#app",            data: {},            router        })    </script></body></html>

三.路由重定向:

路由重定向指的是用户在拜访地址A的时候,强制用户跳转到地址B,从而展现特定的组件页面。

通过路由规定的redirect属性,指定一个新的路由地址,能够很不便地设置路由的重定向。

{path:'/..',redirect: '/...'}
其中path示意重定向的原地址,redirect示意新地址。

比方第二大点的案例中,刚关上的页面如下,在根目录,但咱们想一进入就显示page1,那就给根目录重定向。

批改路由规定如下:

const router = new VueRouter({            routes: [                             {path:'/page1',component:Page1 },                {path:'/page2',component:Page2 },                {path:'/',redirect:'/page1'}            ]        })

看成果,我没点击就默认进入page1了:

四.嵌套路由:

性能如下:

  1. 点击父级路由链接显示模板内容。
  2. 模板内容中又有子级路由链接。
  3. 点击子级路由链接显示子级模板内容。

比方咱们改良第二大点的案例,当点击page2显示page2内容时,page2里又有两个子路由连贯,star和moon,当点击其中一个链接时又能显示对应的star或moon内容。

1.首先给page2组件增加两个子路由链接:

const Page2 = {            template: `                 <div>                 <h1>我是北极光之夜2号</h1>                 <hr/>                 <router-link to="/page2/star">Star</router-link>                 <router-link to="/page2/moon">Moon</router-link>                 <hr/>                 </div>`        }

此时页面也把显示子路由链接进去了:

2.给两个子路由链接增加路由填充位:

const Page2 = {const Page2 = {            template: `                 <div>                 <h1>我是北极光之夜2号</h1>                 <hr/>                 <router-link to="/page2/star">Star</router-link>                 <router-link to="/page2/moon">Moon</router-link>                 <hr/>                 <router-view></router-view>                 </div>`        }

3.设置两个子组件star与moon的内容:

 const Star = {            template: '<h2>我是北极光之夜2号下的star</h2>'        }        const Moon = {            template: '<h2>我是北极光之夜2号下的Moon</h2>'        }

4.配置路由规定:

page2的规定除了path和component属性外,再增加一个children属性,这个属性以数组示意,数组里寄存其子路由的规定,其规定也是一样的,套娃套娃。

const router = new VueRouter({            routes: [                {path:'/page1',component:Page1 },                {                    path:'/page2',                    component:Page2,                     children: [                        {path: '/page2/star',component:Star},                        {path: '/page2/moon',component:Moon}                    ]                }            ]        })

5.成果与单页面代码:

残缺代码:

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title>    <!-- 导入vue文件 -->    <script src="https://unpkg.com/vue/dist/vue.js"></script>    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script></head><body>    <div id="app">       <router-link to="/page1">Page1</router-link>       <router-link to="/page2">Page2</router-link>       <router-view></router-view>    </div>    <script>        const Page1 = {            template: '<h1>我是北极光之夜1号</h1>'        }        const Page2 = {            template: `                 <div>                 <h1>我是北极光之夜2号</h1>                 <hr/>                 <router-link to="/page2/star">Star</router-link>                 <router-link to="/page2/moon">Moon</router-link>                 <hr/>                 <router-view></router-view>                 </div>`        }        const Star = {            template: '<h2>我是北极光之夜2号下的star</h2>'        }        const Moon = {            template: '<h2>我是北极光之夜2号下的Moon</h2>'        }        const router = new VueRouter({            routes: [                {path:'/page1',component:Page1 },                {                    path:'/page2',                    component:Page2,                     children: [                        {path: '/page2/star',component:Star},                        {path: '/page2/moon',component:Moon}                    ]                }            ]        })        const app = new Vue({            el:"#app",            data: {},            router        })    </script></body></html>

五. 动静路由匹配:

1.动静匹配路由根本应用:

如果某些路由规定的一部分是一样的,只有另一部分是动态变化的,那咱们能够把这些动态变化的局部造成路由参数,这些参数就叫做动静路由匹配。简略来说,你先看上面这些路由链接,它们都有/page/,就是前面不一样:

 <router-link to="/page/1">Page1</router-link>   <router-link to="/page/2">Page2</router-link>   <router-link to="/page/3">Page3</router-link>

那该咋配置路由呢?这样吗:

const router = new VueRouter({            routes: [                {path:'/page/1',component:Page},                {path:'/page/2',component:Page},                {path:'/page/3',component:Page}            ]        })

这样万一有很多一个个写岂不是太麻烦了,所以引入参数,在动静扭转的局部定义为参数,参数后面有一个冒号,那下面可简写成如下,动静局部设为参数 :id 。

const router = new VueRouter({            routes: [                {path:'/page/:id',component:Page },            ]        })

在组件能够通过以下语法获取以后路由的参数:

$router.params.参数名称
好,再次批改第二大点的案例实现动静路由匹配:

1.定义路由链接:

<div id="app">   <router-link to="/page/1">Page1</router-link>   <router-link to="/page/2">Page2</router-link>   <router-link to="/page/3">Page3</router-link>   <router-view></router-view>   </div>

2.动静配置路由,参数id:

const router = new VueRouter({    routes: [        {path:'/page/:id',component:Page1 },    ]})

3.设置组件内容,并显示以后路由的参数:

const Page1 = {    template: '<h1>我是北极光之夜1号,以后id为:{{$route.params.id}}</h1>'}

看成果:

2.路由组件传参:

下面的$route与对应路由造成高度耦合,不够灵便啊,所以能够应用props将组件和路由解耦。简略来说,如同也没什么说的,间接看上面实例就能了解了。

2.1 当props为布尔类型:

  const router = new VueRouter({            routes: [ // 设置props,如果props为true,router.params会被设置为组件属性                {path:'/page/:id',component:Page1,props: true },            ]        })                        const Page1 = {// 这时就通过props接管参数,疾速简洁的接管参数id和应用它                    props: ['id'],                    template: '<h1>我是北极光之夜1号,以后id为:{{id}}</h1>'                }

能达到一样的成果,且更灵便了,下面记得反过来,先定义组件才配置路由规定,只是为了直观才这样写:

2.2 当props为对象类型:

           const Page1 = {        // 这时就通过props接管参数,疾速简洁的接管参数对象 并显示                props: ['name','age'],                template: `<h1>我是北极光之夜1号,以后id为:{{id}}                            <hr/>                           姓名为:{{name}} ,年龄为:{{age}} </h1>`                }             const router = new VueRouter({                routes: [            // props为一个参数对象,它会原样设置为组件属性,            // 外面的自定义的参数都能传过来,然而id传不了了                    {path:'/page/:id',component:Page1 , props: {name:'auroras',age: 18} }                ]             })  

成果,对象props对象里的能获取,id就不行了:

2.3 当props为函数类型:

这个就什么都能获取。

    const Page1 = {// 这时就通过props接管参数,疾速简洁的接管参数        props: ['name','age','id'],        template: `<h1>我是北极光之夜1号,以后id为:{{id}}                    <hr/>                   姓名为:{{name}} ,年龄为:{{age}} </h1>`        }     const router = new VueRouter({        routes: [    // props为函数,这个对象接管router对象为本人形参,    // 外面的自定义的参数和id都能传过来            {path:'/page/:id',            component:Page1 ,             props: router => ({id: router.params.id,name:'auroras',age: 18}) }        ]     })  

成果:

以后残缺代码:

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title>    <!-- 导入vue文件 -->    <script src="https://unpkg.com/vue/dist/vue.js"></script>    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script></head><body>    <div id="app">        <router-link to="/page/1">Page1</router-link>        <router-link to="/page/2">Page2</router-link>        <router-link to="/page/3">Page3</router-link>        <router-view></router-view>        </div>            <script>            const Page1 = {        // 这时就通过props接管参数,疾速简洁的接管参数对象                 props: ['name','age','id'],                template: `<h1>我是北极光之夜1号,以后id为:{{id}}                            <hr/>                           姓名为:{{name}} ,年龄为:{{age}} </h1>`                }             const router = new VueRouter({                routes: [            // props为函数,这个对象接管router对象为本人形参,            // 外面的自定义的参数和id都能传过来                    {path:'/page/:id',                    component:Page1 ,                     props: router => ({id: router.params.id,name:'auroras',age: 18}) }                ]             })          const app = new Vue({            el:"#app",            data: {},            router        })    </script></body></html>

六.Vue-Router命名路由:

为更加不便的示意路由的门路,能够给路由规定起一个别名, 即为“命名路由”。持续改良下面的案例解说用法:

1.首先给路由规定加一个name属性,这个就是别名:

const router = new VueRouter({    routes: [        {        name: 'user',        path:'/page/:id',        component:Page1 ,         props: router => ({id: router.params.id,name:'auroras',age: 18}) }    ] }) 

2.在路由链接中应用:

  <div id="app">    <router-link :to="{name:'user',params: {id: 1}}">Page1</router-link>    <router-link to="/page/2">Page2</router-link>    <router-link to="/page/3">Page3</router-link>    <router-view></router-view>    </div>

咱们把第一个路由链接改良,to后面加上冒号,其中name示意匹配的是哪个路由规定,params示意要传递的参数,看上面是一样的成果:

七.编程式导航:

  1. 申明式导航:首先申明式导航是指用户通过点击链接实现导航的形式,比方点击a标签或者路由链接这些实现的跳转。
  2. 编程式导航:编程式导航就是说跳转是因为我点击它,它不是链接,然而它在JavaScript里调用了某个API也实现了跳转。
  3. 罕用的编程式导航API如下:
this.$router.push('要跳转的hash地址')this.$router.go(n)

push里间接放要跳转的哈希地址,go办法实现后退和后退,n代表数组,若n为1代表在历史记录中后退一位,-1代表在历史记录中后退一位。

1. this.$router.push(’ '):

重写一个案例,有page1、page2、page3三个路由链接,而在page3里有一个按钮,这个按钮的作用是点击后返回显示page1的内容。这个按钮可不是申明式导航里的链接,就是一个按钮。

1.定义一般的路由链接:

   <div id="app">    <router-link :to="/page/1">Page1</router-link>    <router-link to="/page/2">Page2</router-link>    <router-link to="/page/3">Page3</router-link>    <router-view></router-view>    </div> 

2.定义3个组件内容,其中给page3组件里放一个按钮,并绑定点击事件,在事件里通过API导航到page1:

const Page1 = {    template: `<h1>我是北极光之夜1号</h1>`}const Page2 = {    template: `<h1>我是北极光之夜2号</h1>`}const Page3 = {    template: `<div>            <h1>我是北极光之夜3号</h1>            <button @click="goPage1">返回page1</button>               </div>`,    methods: {        goPage1(){            this.$router.push('/page/1')        }    },    }

3.路由规定:

const router = new VueRouter({                routes: [                    {path:'/page/1',component: Page1},                    {path:'/page/2',component: Page2},                    {path:'/page/3',component: Page3}                ]             })  

4.看成果:

5.残缺代码:

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title>    <!-- 导入vue文件 -->    <script src="https://unpkg.com/vue/dist/vue.js"></script>    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script></head><body>    <div id="app">        <router-link to="/page/1">Page1</router-link>        <router-link to="/page/2">Page2</router-link>        <router-link to="/page/3">Page3</router-link>        <router-view></router-view>    </div>            <script>            const Page1 = {                template: `<h1>我是北极光之夜1号</h1>`            }            const Page2 = {                template: `<h1>我是北极光之夜2号</h1>`            }            const Page3 = {                template: `<div>                        <h1>我是北极光之夜3号</h1>                        <button @click="goPage1">返回page1</button>                           </div>`,                methods: {                    goPage1(){                        this.$router.push('/page/1')                    }                },                            }             const router = new VueRouter({                routes: [                    {path:'/page/1',component: Page1},                    {path:'/page/2',component: Page2},                    {path:'/page/3',component: Page3}                ]             })          const app = new Vue({            el:"#app",            data: {},            router        })    </script></body></html>

不止href门路,还能够有以下操作:

//字符串模式(门路的名称)router.push('/page1')
//对象的模式router.push({path: '/page1'})
//也能够传递参数,命名的路由router.push({name: '/page1',parmas:{id: 1}})//带查问参数,变成  /page1?p=id 
//这个挺实用的,比方在某些音乐网页,点击歌单后要导航到另一个该歌单具体界面,此时要带id,具体界面靠此id从新发送申请,申请详细信息router.push({parh: '/page1',query:{p: 'id' }})

2. this.$router.go(n):

改良第1小点的案例,当我page3跳到page1时,page1里又有一个返回的按钮。咱们把n设置为-1,他就会在历史记录中后退一位,后退一位就是page3.
批改page1组件内容:

 const Page1 = {                template: `<div>                        <h1>我是北极光之夜1号</h1>                        <button @click="goBack">返回</button>                           </div>`,                  methods: {                    goBack(){                        this.$router.go(-1)                    }            }        }

成果:

点击关注,第一工夫理解华为云陈腐技术~