路由导航守卫和Vue实例生命周期钩子函数的执行顺序?
路由导航守卫都是在Vue实例生命周期钩子函数之前执行的
vue-router有哪几种导航钩子(导航守卫)?
全局守卫:
- 全局前置守卫:beforeEach
router.beforeEach((to, from, next) => { /* 必须调用 `next` */ })
- 全局解析守卫:beforeResolve
router.beforeResolve((to, from, next) => { /* 必须调用 `next` */ })
- 全局后置钩子:afterEach
router.afterEach((to, from) => {})
路由独享守卫
- beforeEnter
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
组件内的守卫
- beforeRouteEnter
- beforeRouteUpdate
- beforeRouteLeave
const Foo = { template: `...`, beforeRouteEnter(to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当守卫执行前,组件实例还没被创建 }, beforeRouteUpdate(to, from, next) { // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 // 可以访问组件实例 `this` }, beforeRouteLeave(to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` } }
讲一下完整的导航守卫流程?
- 导航被触发
- 在失活的组件里调用离开守卫
beforeRouteLeave(to,from.next)
- 调用全局前置守卫
beforeEach((to,from,next)=>{})
- 再重用的组件里调用
beforeRouteUpdate(to,from,next)
守卫 - 在路由配置里调用路由独享的守卫
beforeEnter(to,from,next)
- 解析异步路由组件
- 在被激活的组件里调用
beforeRouteEnter(to,from,next)
- 在所有组件内守卫和异步路由组件被解析之后调用全局解析守卫
beforeResolve((to,from,next)=>{})
- 导航被确认
- 调用全局后置钩子
afterEach((to,from)=>{})
- 触发DOM更新
- 用创建好的实例调用
beforeRouteEnter
守卫传给next的回调函数
导航守卫的三个参数的含义?
- to: 即将要进入的目标路由对象
- from: 当前导航正要离开的路由对象
- next: 此函数必须调用,不然路由跳转不过去
- next(): 进入下一个路由
- next(false): 中断当前的导航
- next('/')或next({ path: '/' }) : 跳转到其他路由,当前导航被中断,进行新的一个导航。
route和router有什么区别?
this.$route
是当前路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数this.$router
是路由实例对象,包括了路由的跳转方式(push(),go()),钩子函数等this.routes
是创建路由实例的配置项,用来配置多个route路由对象
获取路由实例配置项:this.routes = this.$router.options.routes
获取当前页面路由路径
this.$route.path
在vue组件中怎么获取当前的路由信息?
this.$route
怎么重定向页面?
-
重定向path
const router = new Router({ routes: [ {path:'/a', redirect:'/b'} ] })
- 重定向到命名的路由
const router = new Router({ routes: [ {path:'/a', name:'Baa'} ] })
- 可以写成一个方法,动态返回重定向的目标
const router = new Router({ routes: [ { path:'/a', redirect: to => { return {path: '/bbb', query: {a: 1}} } } ] })
vue-router怎么配置404页面?
在router.js中,由于路由是从上到下执行的,只要在路由配置中最后面放个*号就可以了
const router = new Router({ routes: [ { path: '*', redirect: '/404' } ] })
说说你对router-link的了解?(待完善)
<router-link>是Vue-Router的内置组件,在具有路由功能的应用中,作为声明式的导航使用
<router-link>有8个props,作用如下:
- to:必填,标识目标路由的链接,当被点击后,内部会立刻把to的值传到router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象
- 注意path存在时,params不起作用,只能用query
- replace:默认值为false,若设置的话,当点击时,会调用router.replace()而不是router.push(),于是导航后不会留下history记录
- append:设置append属性后,则在当前(相对)路径前添加基路径
-
- 设置
append
属性后,则在当前 (相对) 路径前添加基路径。例如,我们从/a
导航到一个相对路径b
,如果没有配置append
,则路径为/b
,如果配了,则为/a/b
- 设置
- tag:让<router-link>渲染成tag设置的标签,如tag="li",就会渲染成<li>跳转</li>
- active-class:默认值为router-link-acitve,设置链接激活时使用的CSS类名,默认值可以通过路由的构造选项linkActiveClass来全局配置
- exact-active-class:默认值为router-link-exact-active,设置连接呗精确匹配的时候应该激活的class,默认值可以通过路由构造函数选项linkExactActiveClass进行全局配置
- exact:是否精确匹配,默认为false
- event:声明可以用来触发导航的事件,可以是一个字符串或是一个包含字符串的数组,默认是click
<router-link to="home">Home</router-link> <router-link :to="'home'">Home</router-link> <router-link :to="{ path: 'home' }">Home</router-link> <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link> <router-link :to="{ path: 'user', query: { userId: 123 }}">User</router-link>
说说active-class是哪个组件的属性?
<router-link/>组件的属性,设置连接激活时使用的css类名,默认值可以通过路由的构造选项linkActiveClass来全局配置
css
.nav .active{ color: red; }
router.js
export default new Router({ linkActiveClass:'active', routes:[] })
路由之间跳转有哪些方式?
- 声明式:通过内置组件<router-link>跳转
<router-link :to="/home">
- 编程式:通过调用router实例的push方法
this.$router.push({path: "home", query: {num: 1}})
或
this.$router.replace({path:'/home'})
vur-router传参?
- query传参和接收参数
this.$router.push({ path:'/home', query:{id:1} })
query接参:this.$route.query.id
- params传参和接收参数
this.$router.push({ name:'Home', params:{a:1} })
params接参:
this.$route.params.userId
注意:params传参,push里面只能是name:'xxxx',不能是path:'/xxx',因为params只能用name来引入路由,如果这里写成了path,目标页面接收参数会是undefined
如何监听路由参数的变化?
有两种方法可以监听路由参数的变化,但是只能用在包含<router-view/>的组件内
- watch监听$route对象
watch:{
'$route'(to,from){
console.log(to, from)
}
}
2. beforeRouteUpdate
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
query和params的区别?
- query刷新页面参数不会消失,params刷新页面参数会消失,可以考虑本地存储解决
- query传参会显示url地址上,params传参并不会显示在地址栏
切换路由时,需要保存草稿的功能,怎么实现?
使用<keep-alive>包裹<router-view>
<keep-alive> <router-view></router-viewe </keep-alive>
vue路由中去掉 #
路由router.js配置mode:'history'
const router = new Router({ mode:'history' })
history模式
history模式利用HTML5 History Interface中新增的pushState()和replaceState()方法,这两个方法应用于浏览器的历史记录栈,提供了对历史记录进行修改的功能,只是当他们进行修改时,虽然修改了url,例如http://aaaa.com/user/id,相比hash模式更加好看,需要注意的是,history模式需要后台配置支持,如果后台没有正确配置,访问时会返回404,通过history api,我们丢弃了丑陋的#,但是也有一个缺点,当刷新时,如果服务器中没有相应的响应或者资源,会刷新一个404。
hash模式和history模式相比较
hash模式:
- url路径会出现”#“字符
- hash值不包括在http请求中,他是交由前端路由处理,所以改变hash值时不会刷新页面,也不会向服务器发送请求
- hash值的改变会触发hashchange事件
history模式:
- url值不会出现“#”字符
- 整个地址重新加载,可以保存历史记录,方便前进后退
- 依赖于H5 API和后台配置,没有后台配置的话,页面刷新会出现404
- 前端的url必须和实际向后端发起请求的url一直,如http://aaaa.com/user/id,后端如果没有对user/id的路由做处理,将返回404错误