中文文档:https://router.vuejs.org/zh/vue
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。路由实际上就是能够理解为指向,就是我在页面上点击一个按钮须要跳转到对应的页面,这就是路由跳转;
web
首先咱们来学习三个单词(route,routes,router):vue-router
route:首先它是个单数,译为路由,即咱们能够理解为单个路由或者某一个路由;vue-cli
routes:它是个复数,表示多个的集合才能为复数;即咱们能够理解为多个路由的集合,JS中表示多种不一样状态的集合的形式只有数组和对象两种,事实上官方定义routes是一个数组;因此咱们记住了,routes表示多个数组的集合;npm
router:译为路由器,上面都是路由,这个是路由器,咱们能够理解为一个容器包含上述两个或者说它是一个管理者,负责管理上述两个;举个常见的场景的例子:当用户在页面上点击按钮的时候,这个时候router就会去routes中去查找route,就是说路由器会去路由集合中找对应的路由;编程
咱们结合一个小demo来看(文章有点长,耐心慢慢看,学得慢才能进步的快,固然能够跟着一块儿敲):json
首先须要安装vue-cli来构建一个vue的开发环境(怎么安装这里不讲,本身百度去,若是这种问题本身都解决不了的话,后面的知识可能对你来讲收益不大)数组
安装完vue-cli以后,咱们的项目目录结构以下:app
而后咱们在命令行中输入npm install vue-router -g来安装vue-router,安装完以后咱们能够打开package.json文件,在package.json文件中能够看到vue-router的版本号;
函数
到这一步咱们的准备工做就完成了,要进行写demo了;
咱们在src目录下新建三个文件,分别为page1.vue和page2.vue以及router.js:
page1.vue:
<template> <div> <h1>page1</h1> <p>{{msg}}</p> </div> </template> <script> export default { data () { return { msg: "我是page1组件" } } } </script>
page2.vue:
<template> <div> <h1>page2</h1> <p>{{msg}}</p> </div> </template> <script> export default { data () { return { msg: "我是page2组件" } } } </script>
router.js
//引入vue import Vue from 'vue'; //引入vue-router import VueRouter from 'vue-router'; //第三方库须要use一下才能用 Vue.use(VueRouter) //引用page1页面 import page1 from './page1.vue'; //引用page2页面 import page2 from './page2.vue'; //定义routes路由的集合,数组类型 const routes=[ //单个路由均为对象类型,path表明的是路径,component表明组件 {path:'/page1',component:page1}, {path:"/page2",component:page2} ] //实例化VueRouter并将routes添加进去 const router=new VueRouter({ //ES6简写,等于routes:routes routes }); //抛出这个这个实例对象方便外部读取以及访问 export default router
这里咱们再修改一下main.js
import Vue from 'vue' import App from './App' //引用router.js import router from './router.js' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', //必定要注入到vue的实例对象上 router, components: { App }, template: '<App/>' })
修改App.vue
<template> <div id="app"> <img src="./assets/logo.png"> <div> //router-link定义页面中点击触发部分 <router-link to="/page1">Page1</router-link> <router-link to="/page2">Page2</router-link> </div> //router-view定义页面中显示部分 <router-view></router-view> </div> </template> <script> export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
就这样,咱们的页面就能够进行路由跳转和切换了,路由的基本使用就完成了;可是有个问题就是咱们第一次进去是看不到路由页面的,这是由于咱们没有设置默认值,咱们首次进入的时候路径是为空的,那么咱们能够这么解决:
router.js
import Vue from 'vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter) import page1 from './page1.vue'; import page2 from './page2.vue'; import user from './user.vue' const routes=[ {path:'/page1',component:page1}, {path:"/page2",component:page2}, //能够配置重定向 {path:'',redirect:"page1"} //或者从新写个路径为空的路由 {path:"",component:page1} ] const router=new VueRouter({ routes }); export default router
上面的两种解决方案都是能够解决的,配置重定向的意思就是当匹配到路径为空的时候,就会重定向到page1,执行page1的路由;或者咱们也能够从新配置个路由,路径为空的时候router-view展现page1的页面;
用重定向和单独配置路由的区别:
重定向其实是当匹配到路径符合条件的时候去执行对应的路由,固然这个时候的url上面的地址显示的是对应的路由,页面也是对应的路由页面;
从新配置路由是当匹配到路径符合条件的时候,router-view页面展现部分负责拿符合条件路由的页面来展现,实际上url是没有发生变化的;
那么还有些复杂状况,是基本路由实现不了的;咱们来接着往下看
动态路由匹配:
其实咱们的生活中有不少这样的例子,不知道你们留意没有?好比一个网站或者后台管理系统中,在咱们登陆以后,是否是一般会有一个欢迎回来,XXX之类的提示语,这个咱们就能够经过动态路由来实现这个效果;
首先在src目录下新建一个user.vue文件:
<template> <div> <h1>user</h1> //这里能够经过$route.params.name来获取路由的参数 <p>欢迎回来,{{$route.params.name}}</p> </div> </template> <script> export default { data () { return { msg: "我是page1组件" } } } </script>
而后咱们修改App.vue文件的代码:
<template> <div id="app"> <img src="./assets/logo.png"> <div> <router-link to="/page1">Page1</router-link> <router-link to="/page2">Page2</router-link> </div> //添加两个router-link标签 <div> <router-link to="/user/xianyu">动态路由咸鱼</router-link> <router-link to="/user/mengxiang">动态路由梦想</router-link> </div> <router-view></router-view> </div> </template> <script> export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
修改咱们的router.js
import Vue from 'vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter) import page1 from './page1.vue'; import page2 from './page2.vue'; import user from './user.vue' const routes=[ {path:'/page1',component:page1}, {path:"/page2",component:page2}, // {path:'',redirect:"page1"} {path:"",component:page1}, //使用冒号标记,当匹配到的时候,参数值会被设置到this.$route.params中 {path:"/user/:name",component:user} ] const router=new VueRouter({ routes }); export default router
配置好了,不出意外是能正常运行的,咱们来看一下效果:
动态路由匹配给咱们提供了方便,使得咱们经过配置一个路由来实现页面局部修改的效果,给用户形成一种多个页面的感受,是否是很酷!!!
酷的同时也会给咱们带来一些问题,由于使用路由参数时,从/user/xianyu导航到/user/mengxiang,原来的组件实例会被复用,两个路由都渲染同个组件,比起销毁再建立,显示复用显得效率更高,带来的的只管问题就是生命周期钩子函数不会再被调用,也就是不会再被触发;可是办法总比问题多,咱们能够经过监听$route对象来实现;
修改user.vue的代码
<template> <div> <h1>user</h1> <p>欢迎回来,{{msg}}</p> </div> </template> <script> export default { data () { return { // msg: "我是page1组件" msg:"" } }, watch:{ //to表示即将要进入的那个组件,from表示从哪一个组件过来的 $route(to,from){ this.msg=to.params.name; console.log(111); } } } </script>
效果图以下:
咱们能够很明显的看到咱们监听的$route对象被触发了,控制台也输出了;
下面咱们来一块儿看一下嵌套路由:
嵌套路由:
不少时候咱们的页面结构决定了咱们可能须要嵌套路由,好比当咱们进入主页以后有分类,而后当选择其中一个分类以后进入对应的详情,这个时候咱们就能够用到嵌套路由;官方文档中给咱们提供了一个children属性,这个属性是一个数组类型,里面实际放着一组路由;这个时候父子关系结构就出来了,因此children属性里面的是路由相对来讲是children属性外部路由的子路由;
好记性不如烂代码,让咱们经过代码来看一看:
首先在咱们的src目录下新建两个vue文件,分别是phone.vue和computer.vue
phone.vue
<template> <div> <p>{{msg}}</p> </div> </template> <script> export default { data () { return { msg: "嵌套手机组件" } } } </script>
computer.vue
<template> <div> <p>{{msg}}</p> </div> </template> <script> export default { data () { return { msg: "嵌套电脑组件" } } } </script>
而后咱们再修改咱们的App.vue文件:
<template> <div id="app"> <img src="./assets/logo.png"> <div> <router-link to="/page1">Page1</router-link> </div> <router-view></router-view> </div> </template> <script> export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
经过上面的App.vue文件咱们能够看到,咱们此时页面只有一个page1的标签了;
咱们再来修改router.js
import Vue from 'vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter) import page1 from './page1.vue'; import page2 from './page2.vue'; import user from './user.vue'; import phone from './phone.vue'; import computer from './computer.vue' const routes=[ { path:'/page1', component:page1, children: [ { path: "phone", component: phone }, { path: "computer", component: computer }, ] }, // {path:"/page2",component:page2}, // // {path:'',redirect:"page1"} // {path:"",component:page1}, // {path:"/user/:name",component:user} ] const router=new VueRouter({ routes }); export default router
为了你们看的直观点,其余路由所有注释了,页面只剩下/page1这一个路由了;
上面说到了,children属性其实就是一个子路由集合,数组结构里面放着子路由;
效果图以下:
路由导航两种方式:
标签导航:标签导航<router-link><router-link>是经过转义为<a></a>标签进行跳转,其中router-link标签中的to属性会被转义为a标签中的href属性;
//跳转到名为user路由,并传递参数userId <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
编程式导航:咱们能够经过this.$router.push()这个方法来实现编程式导航,固然也能够实现参数传递,这种编程式导航通常是用于按钮点击以后跳转
router.push({ name: 'user', params: { userId: 123 }})
这二者都会把路由导航到user/123路径
命名路由:
有的时候,经过一个名称来标识一个路由显得更方便一些,因此官方为了方便咱们偷懒,又给咱们在路由中添加了一个name属性,命名这个属性以后咱们访问这个属性就等于直接访问到路由;
普通路由:
router.push({ path: '/user/:userId', params: { userId: 123 }})
命名路由:
router.push({ name: 'user', params: { userId: 123 }})
其实二者并无什么区别,只是提供了两种方式来访问路由,能够经过路径来匹配也能够经过别名来匹配;
今天的文章就到这里,下篇咱们一块儿来学习Vue路由守卫!!!
加油!!