路由
路由起步
监听地址栏的改变.根据改变渲染不同的组件
-
基本使用
下载安装路由 npm install vue-router
-
创建路由表(项目下的一个router.js文件)
-
引入vue和vue-router
import vue from 'vue' import vueRouter from 'vue-router'
-
在vue中使用vue-router
vue.use(vueRouter)
-
创建路由实例 确定路径和组件的对应关系 "/"表示的是根目录
let router = new vueRouter({ routes:[ { path:'/son1',//地址栏的地址 component:son1//如果你的地址栏变成son1我就渲染son1组件 }, { path:'/son2',//同上 component:son2 } ] })
-
抛出路由实例
export default router
-
-
在main.js 里注册路由
import Vue from 'vue' import App from './App.vue' import router from './router/router'//引入路由文件 Vue.config.productionTip = false new Vue({ router:router, //注册路由 // 渲染一个app组件 render: h => h(App) }).$mount('#app')
-
完成main.js注册后就可以使用两个组件
-
<router-link> 控制地址栏的改变
-
有一个to属性来控制地址栏变成啥样
- to属性后面跟对象要加 : 号
-
-
可以跟组件名
<template> <div id="app"> 这是根组件 <!-- <banner></banner> <box></box> --> <router-link to = '/son1'>son1</router-link> <router-link to = '/son2'>son2</router-link> <router-view></router-view> </div> </template>
- 也可以跟path路径名(前面要加:号) ```js <router-link :to ='{path:"/recommend"}' active-class = 'hehe'>recommend</router-link>
-
路由命名..就是在路由注册表中用name给路由命名
-
也可以跟name属性(也要加冒号)
<router-link :to ='{name:"hanjie"}' active-class = 'hehe'>recommend</router-link>
-
-
<router-link> 默认渲染成<a>标签
tag 用来控制<router-link>渲染成什么标签
-
active-class 激活状态类名,只有选中状态才会添加class名
```js <router-link to = '/son1' tag = 'span' active-class = 'hehe'>son1</router-link>
-
<router-view> 开启一片空间,渲染指定的组件
-
在哪使用直接在哪用就行,起到一个占位的作用.根据地址栏渲染不同的组件.可以写多个.
```js <router-view></router-view> ```
-
路由模式 mode
在路由注册表中可以控制路由模式
历史模式(history) 地址栏中没有#符号
-
hash模式 地址栏中有#符号
let router = new vueRouter({ mode:'history', routes:[ { path:'/son1',//地址栏的地址 component:son1//如果你的地址栏变成son1我就渲染son1组件 }, { path:'/son2',//同上 component:son2 } ]
路由命名
-
路由命名.
- .就是在路由注册表中用name给路由命名也可以实现跳转
- 也可以跟name属性(也要加冒号)
- .就是在路由注册表中用name给路由命名也可以实现跳转
<router-link :to ='{name:"hanjie"}' active-class = 'hehe'>recommend</router-link>
-
命名视图
-
在一个页面渲染多个组件时可以使用
- 在注册表中 把component修改成components
{ path:'/namerouter',//同上 name:'namerouter', components:{ default:son1, //默认渲染组件 a:son2, b:son3 } } ]
- 在使用组件文档处可以写成这种模式..
<router-link :to ='{name:"namerouter"}' active-class = 'hehe'>namerouter"</router-link> <router-view></router-view> //不加name默认是default:son1 <router-view name='a'></router-view> <router-view name='b'></router-view>
-
重定向和别名
-
重定向(redirect)
-
刚进入页面的时候不能什么组件都不显示,所以要设置一个默认显示的组件
{ path:'/', //如果地址栏上只显示/的话 redirect:'/son1' //那就跳转到'./son1' }
-
声明式导航和编程式导航
-
声明式导航
- 通过标签实现跳转页面..比如<a>标签
- 在路由中使用<router-link>进行组件切换的就是声明式导航
-
编程式导航
通过代码实现跳转页面的...比如js中的window.location.href=‘path’
-
在路由中由对象下的api 进行组件切换的叫做编程式导航.
-
常用的有三种方法 push replace go (back,forward(go方法相当于这两种方法.))
-
首先添加一个点击事件
<span @click="go('/son3')">son3</span>
-
可以接受字符串/对象/的传参
go(path){ console.log(this) this.$router.push(path) this.$router.push({path:path}) this.$router.push({name:'起的名字'}) } }
-
三种方法的不同
- push每次跳转.地址都会保存到地址栈中,所以可以一级一级的返回
- replace 返回会直接返回到最初的页面
- go(可以跟数字来指定回退几步)
-
-
路由传参
切换组件的时候给目标组件传一个参数
切换的时候传递参数
-
切换完毕 在目标组件接受参数
-
动态路由
- 传参
- 路径中有最少一项是变量(这个变量可以是任何数据)
- 在地址栏中必须要输入/son2/任意数据/任意数据..这样的格式才能访问组件
- 路径中有最少一项是变量(这个变量可以是任何数据)
{ path:'/son2/:hehe/:xixi',//同上 component:son2 },
- 接受参数
- 在目标组件中(如上图代码就是在son2组件中)通过this.$route.params来接受数据
- 传参
-
query传参
-
传参
相当于get传递参数.
数据会出现在地址栏上,缺少安全性
-
数据有长度限制
this.$router.push('/name:us-123&ps=123') this.$router.push({path:'/name',query:{us:123,ps:134}})
-
接受数据
- 在目标组件里通过this.$router.query()进行接受
-
-
params传参
-
传参
不会出现地址栏上,\
没有长度限制
-
不能和path一起使用
this.$router.push({name:'hehe',params:{us:123,ps:123}})
-
接收
- 在目标组件里通过this.$router.param()进行接受
-
-
嵌套路由又称子路由
在一个路由组件里嵌套别的路由
-
在路由注册表下需要嵌套的组件中使用children属性
- 注意不用加'/'
{ path:'/my', component:My, children:[ { path:'userinfo', component:UserInfo }, { path:'userlogin', component:UserLogin } ] },
-
在my.vue中使用二级路由
<router-view></router-view>
导航守卫(路由拦截器)
就是切换组件路由时起到一个拦截作用,可以先判断下是否符合某些条件在决定是否切换
某些页面登录之后才能访问,没有登录不能访问
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用离开守卫。
- 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫 (2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 用创建好的实例调用
beforeRouteEnter
守卫中传给next
的回调函数。
全局前置守卫
不管哪个路由发生改变都可以触发全局前置守卫
在路由创建表中(自己另起一行)
-
三个参数
- to 到哪去 想要切换哪个组件
- from 从哪来 从哪个组件切换过来的
- next 是否允许切换
- 后面可以跟一个组件路径.指定切换到指定的组件
router.beforeEach((to, from, next) => { console.log(from)//从哪而来 console.log(to)//到哪去 let islogin = true; if(to.path==='/singer'){ if(islogin){ next() }else{ next('/my/userlogin') } }else{ next() //可以去 } })
路由独享的守卫(局部拦截器)
语法和全局守卫一样,只是定义为位置不一样.
-
在哪个组件配置里定义的就在那个组件有效
{ path:'/singer', component:Singer, beforeEnter: (to, from, next) => { console.log('什么么') next() } },
全局后置钩子
-
组件跳转完成之后触发
router.afterEach((to, from) => { })
全局解析守卫
- 和全局前置守卫用法是一样的.只是调用的时间不一样
组件内置守卫
直接修改动态导航时不会已引起组件的重新创建 组件是复用的
组件内的守卫
beforeRouterEnter 进入组件之前
beforeRouterUpdate
当前组件路由发生修改
动态导航修改组件复用不会重新创建销毁
监听路由发生改变
beforeRouterLeave 组件离开的时候触发