目录
1、vuerouter的几种传参方式(这个是我之前面试的时候问到的,这次重读vuerouter文档做了下总结)
2、动态路由匹配时如何让响应参数的变化(这个是我之前写项目时遇到的问题)
3、简述vuerouter的hash模式和history模式(面试)
1、vuerouter的几种传参方式(这个是我之前面试的时候问到的,这次重读vuerouter文档做了下总结)
**声明式导航:<router-link :to="...">
<router-link to="news">click to news page</router-link>
//根据路由名称
<router-link :to="{ name: 'news', params: { userId: 1111}}">click to news page</router-link>
//根据路由地址
<router-link :to="{ path: '/news', query: { userId: 1111}}">click to news page</router-link>
**编程式导航:router.push(...) 官网地址
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
如果提供了
path
,params
会被忽略,上述例子中的query
并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的name
或手写完整的带有参数的path
:
const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
获取路由参数
this.$route.params 或
this.$route.query
2、动态路由匹配时如何让响应参数的变化(这个是我之前写项目时遇到的问题)
提醒一下,当使用路由参数时,例如从
/user/foo
导航到/user/bar
,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
解决:
**在被复用的组件中监听路由
watch: {
$route(to, from) {
// 对路由变化作出响应...
}
}
**在被复用的组件中使用导航守卫
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
3、简述vuerouter的hash模式和history模式(面试)
- hash —— 即地址栏 URL 中的 # 符号。比如这个 URL:http://www.abc.com/#/hello hash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。(仅 hash 符号之前的内容会被包含在请求中,如 http://www.abc.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误)原链接
- history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。(但因为vue应用是一个单页客户端应用,如果后台没有正确的配置,直接访问http://www.abc.com/hello/id就会返回404)
在vue中如果要使用history模式,一定要在后台配置好,否则刷新会报404(在实际开发中遇到的问题)
4、简述vuerouter的导航守卫
**全局守卫
1)全局前置守卫 router.beforeEach
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中
2)全局解析守卫 router.beforeResolve
router.afterEach((to, from) => {
// ...
})
这和
router.beforeEach
类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
3)全局后置钩子
router.afterEach((to, from) => {
// ...
})
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受
next
函数也不会改变导航本身
**路由独享守卫--直接在路由配置上进行定义
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
**组件内的守卫
beforeRouteEnter
beforeRouteUpdate
(2.2 新增)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`
}
}