提交 855292dc 编写于 作者: Z zhaoshuangshi

2-2下面所有习题进行优化修改

上级 b1590f81
# vue-router是什么?
 <div style="color: pink;font-size:22px;font-weight:700">小常识:</div>
<br>
**概念**
路由的本质就是一种对应关系,比如说我们在url地址中输入我们要访问的url地址之后,浏览器要去请求这个url地址对应的资源。
那么url地址和真实的资源之间就有一种对应的关系,就是路由。
**路由分为前端路由和后端路由**
1).后端路由是由服务器端进行实现,并完成资源的分发
后端路由性能相对前端路由来说较低,所以,我们接下来主要学习的是前端路由
2).前端路由是依靠hash值(锚链接)的变化进行实现
前端路由的基本概念:根据不同的事件来显示不同的页面内容,即事件与事件处理函数之间的对应关系
前端路由主要做的事情就是监听事件并分发执行事件处理函数
**Vue Router 简介**
它是一个Vue.js官方提供的路由管理器。是一个功能更加强大的前端路由器,推荐使用。
Vue Router和Vue.js非常契合,可以一起方便的实现SPA(single page web application,单页应用程序)应用程序的开发。
Vue Router依赖于Vue,所以需要先引入Vue,再引入Vue Router
**Vue Router的功能**
嵌套路由映射
动态路由选择
模块化、基于组件的路由配置
路由参数、查询、通配符
展示由 Vue.js 的过渡系统提供的过渡效果
细致的导航控制
自动激活 CSS 类的链接
HTML5 history 模式或 hash 模式
可定制的滚动行为
URL 的正确编码
<br>
 <div style="color: #8E7CC3;font-size:22px;font-weight:700">小测试:</div>
根据上方资料,以下对于vue-router说法不正确的是?<br/><br/>
以下对于vue-router说法不正确的是?<br/><br/>
## 答案
vue-router不支持模块化、基于组件的路由配置
vue-router 暂不支持模块化、基于组件的路由配置。
## 选项
### A
vue-router可以嵌套路由映射
用 Vue + Vue Router 创建单页应用非常简单:通过 Vue.js,我们已经用组件组成了我们的应用。当加入 Vue Router 时,我们需要做的就是将我们的组件映射到路由上,让 Vue Router 知道在哪里渲染它们。
### B
vue-router借助Vue实现响应式的路由,因此只能用于vue
Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。
### C
vue-router 的常用模式有hash和history两种
hash和history是vue-router的常用的模式。
# 路由安装
 <div style="color: pink;font-size:22px;font-weight:700">小常识:</div>
<br>
**直接下载 / CDN**
```javascript
https://unpkg.com/vue-router@4
```
Unpkg.com 提供了基于 npm 的 CDN 链接。上述链接将始终指向 npm 上的最新版本。 你也可以通过像 `https://unpkg.com/vue-router@3.0.0/dist/vue-router.js` 这样的 URL 来使用特定的版本或 Tag。
**npm**
```javascript
npm install vue-router@4
```
**开发版本构建**
如果你想使用最新的开发版本,你需要直接从 GitHub 上克隆并自己构建 vue-router。
```javascript
git clone https://github.com/vuejs/vue-router.git node_modules/vue-router
cd node_modules/vue-router
npm install
npm run build
```
<br>
 <div style="color: #8E7CC3;font-size:22px;font-weight:700">小测试:</div>
根据上方资料,以下关于vue-router的安装说法不正确的是?<br/><br/>
以下关于vue-router的安装说法不正确的是?<br/><br/>
## 答案
https://unpkg.com/vue-router@4 此链接始终指向最新版本
Unpkg.com 提供的 CDN 链接不是基于 npm 的
## 选项
### A
Unpkg.com 提供的 CDN 链接不是基于 npm 的
https://unpkg.com/vue-router@4 此链接始终指向最新版本
### B
如果想使用最新的开发版本,需要直接从 GitHub 上克隆并自己构建 vue-router
你也可以通过像 `https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js` 这样的 URL 来使用特定的版本或 Tag
### C
可以直接使用npm进行安装
用户可以直接使用npm或者yarn进行安装
# 编程式的导航
 <div style="color: pink;font-size:22px;font-weight:700">小常识:</div>
<br>
**编程式导航**
除了使用 `<router-link>` 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
**导航到不同的位置**
注意:在 Vue 实例中,你可以通过 `$router` 访问路由实例。因此你可以调用 `this.$router.push`
想要导航到不同的 URL,可以使用 `router.push` 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。
当你点击 `<router-link>` 时,内部会调用这个方法,所以点击 `<router-link :to="...">` 相当于调用 `router.push(...)`
|声明式 | 编程式 |
|--|--|
| `<router-link :to="...">` | `router.push(...)` |
该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:
```javascript
// 字符串路径
router.push('/users/eduardo')
// 带有路径的对象
router.push({ path: '/users/eduardo' })
// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })
// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })
// 带 hash,结果是 /about#team
router.push({ path: '/about', hash: '#team' })
```
注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path :
```javascript
const username = 'eduardo'
// 我们可以手动建立 url,但我们必须自己处理编码
router.push(`/user/${username}`) // -> /user/eduardo
// 同样
router.push({ path: `/user/${username}` }) // -> /user/eduardo
// 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
router.push({ name: 'user', params: { username } }) // -> /user/eduardo
// `params` 不能与 `path` 一起使用
router.push({ path: '/user', params: { username } }) // -> /user
```
由于属性 `to``router.push` 接受的对象种类相同,所以两者的规则完全相同。
`router.push` 和所有其他导航方法都会返回一个 Promise,让我们可以等到导航完成后才知道是成功还是失败。我们将在 Navigation Handling 中详细介绍。
**替换当前位置**
它的作用类似于 router.push,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样——它取代了当前的条目。
| 声明式 | 编程式 |
|--|--|
| `<router-link :to="..." replace>` | router.replace(...) |
也可以直接在传递给 `router.push``routeLocation` 中增加一个属性 `replace: true :`
```javascript
router.push({ path: '/home', replace: true })
// 相当于
router.replace({ path: '/home' })
```
**横跨历史**
该方法采用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于 window.history.go(n)。
例子
```javascript
// 向前移动一条记录,与 router.forward() 相同
router.go(1)
// 返回一条记录,与router.back() 相同
router.go(-1)
// 前进 3 条记录
router.go(3)
// 如果没有那么多记录,静默失败
router.go(-100)
router.go(100)
```
**篡改历史**
你可能已经注意到,`router.push、router.replace``router.go``window.history.pushState、window.history.replaceState``window.history.go` 的翻版,它们确实模仿了 `window.history 的 API`
因此,如果你已经熟悉 Browser History APIs,在使用 Vue Router 时,操作历史记录就会觉得很熟悉。
值得一提的是,无论在创建路由器实例时传递什么样的`history` 配置,`Vue Router` 的导航方法`(push、replace、go)`都能始终如一地工作。
<br>
 <div style="color: #8E7CC3;font-size:22px;font-weight:700">小测试:</div>
观察下列编程式导航,描述不正确的是?<br/><br/>
......@@ -118,8 +15,8 @@ router.push({ path: '/user', params: { username:'eduardo' } }) 导航的结
### B
带查询参数的导航router.push({ path: '/register', query: { plan: 'private' } })
当指定 params 时,可提供 string 或 number 参数(或者对于可重复的参数可提供一个数组)。任何其他类型(如 undefined、false 等)都将被自动字符串化。
### C
to 与 router.push 接受的对象种类相同,所以两者的规则完全相同。
当你点击 `<router-link>` 时,内部会调用这个方法,所以点击 `<router-link :to="...">` 相当于调用 router.push(...) :
# 动态路由
 <div style="color: pink;font-size:22px;font-weight:700">小常识:</div>
<br>
**动态路由**
对路由的添加通常是通过 routes 选项来完成的,但是在某些情况下,你可能想在应用程序已经运行的时候添加或删除路由。具有可扩展接口(如 Vue CLI UI )这样的应用程序可以使用它来扩展应用程序。
**添加路由**
动态路由主要通过两个函数实现。`router.addRoute() 和 router.removeRoute()`。它们只注册一个新的路由,也就是说,如果新增加的路由与当前位置相匹配,就需要你用 `router.push() 或 router.replace()` 来手动导航,才能显示该新路由。我们来看一个例子:
想象一下,只有一个路由的以下路由:
```javascript
const router = createRouter({
history: createWebHistory(),
routes: [{ path: '/:articleName', component: Article }],
})
```
进入任何页面,`/about,/store`,或者 `/3-tricks-to-improve-your-routing-code` 最终都会呈现 Article 组件。如果我们在 /about 上添加一个新的路由:
```javascript
router.addRoute({ path: '/about', component: About })
```
页面仍然会显示 Article 组件,我们需要手动调用 `router.replace()` 来改变当前的位置,并覆盖我们原来的位置(而不是添加一个新的路由,最后在我们的历史中两次出现在同一个位置):
```javascript
router.addRoute({ path: '/about', component: About })
// 我们也可以使用 this.$route 或 route = useRoute() (在 setup 中)
router.replace(router.currentRoute.value.fullPath)
```
记住,如果你需要等待新的路由显示,可以使用 await router.replace()。
在导航守卫中添加路由#
如果你决定在导航守卫内部添加或删除路由,你不应该调用 `router.replace()`,而是通过返回新的位置来触发重定向:
```javascript
router.beforeEach(to => {
if (!hasNecessaryRoute(to)) {
router.addRoute(generateRoute(to))
// 触发重定向
return to.fullPath
}
})
```
上面的例子有两个假设:第一,新添加的路由记录将与 to 位置相匹配,实际上导致与我们试图访问的位置不同。第二,`hasNecessaryRoute()` 在添加新的路由后返回 false,以避免无限重定向。
因为是在重定向中,所以我们是在替换将要跳转的导航,实际上行为就像之前的例子一样。而在实际场景中,添加路由的行为更有可能发生在导航守卫之外,例如,当一个视图组件挂载时,它会注册新的路由。
**删除路由**
有几个不同的方法来删除现有的路由:
通过添加一个名称冲突的路由。如果添加与现有途径名称相同的途径,会先删除路由,再添加路由:
```javascript
router.addRoute({ path: '/about', name: 'about', component: About })
// 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的
router.addRoute({ path: '/other', name: 'about', component: Other })
```
通过调用 router.addRoute() 返回的回调:
```javascript
const removeRoute = router.addRoute(routeRecord)
removeRoute() // 删除路由如果存在的话
```
当路由没有名称时,这很有用。
通过使用 router.removeRoute() 按名称删除路由:
```javascript
router.addRoute({ path: '/about', name: 'about', component: About })
// 删除路由
router.removeRoute('about')
```
需要注意的是,如果你想使用这个功能,但又想避免名字的冲突,可以在路由中使用 Symbol 作为名字。
当路由被删除时,所有的别名和子路由也会被同时删除
**添加嵌套路由**
要将嵌套路由添加到现有的路由中,可以将路由的 name 作为第一个参数传递给 `router.addRoute()`,这将有效地添加路由,就像通过 children 添加的一样:
```javascript
router.addRoute({ name: 'admin', path: '/admin', component: Admin })
router.addRoute('admin', { path: 'settings', component: AdminSettings })
这等效于
router.addRoute({
name: 'admin',
path: '/admin',
component: Admin,
children: [{ path: 'settings', component: AdminSettings }],
})
```
**查看现有路由**
`Vue Router` 提供了两个功能来查看现有的路由:
```javascript
router.hasRoute()检查路由是否存在
router.getRoutes()获取一个包含所有路由记录的数组
```
<br>
 <div style="color: #8E7CC3;font-size:22px;font-weight:700">小测试:</div>
根据上方小常识,以下关于动态路由的说法不正确的是?<br/><br/>
下列关于动态路由的说法不正确的是?<br/><br/>
## 答案
路径参数不接受 正则表达式
对路由的添加通常是通过 routes 选项来完成的,所以在应用程序已经运行的时候是不能支持路由的添加或删除的。
## 选项
### A
动态路由的路径参数 用冒号 : 表示
在 Vue Router 中路径参数 用冒号 : 表示。当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来。
### B
要对同一个组件中参数的变化做出响应的话,你可以简单地 watch $route 对象上的任意属性
动态路由主要通过两个函数实现。router.addRoute() 和 router.removeRoute()。
### C
当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来
如果新增加的路由与当前位置相匹配,就需要你用 router.push() 或 router.replace() 来手动导航,才能显示该新路由。
# 路由组件传参
 <div style="color: pink;font-size:22px;font-weight:700">小常识:</div>
<br>
**将 props 传递给路由组件**
在你的组件中使用 `$route` 会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。虽然这不一定是件坏事,但我们可以通过 props 配置来解除这种行为:
我们可以将下面的代码
```javascript
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
const routes = [{ path: '/user/:id', component: User }]
```
替换成
```javascript
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const routes = [{ path: '/user/:id', component: User, props: true }]
```
这允许你在任何地方使用该组件,使得该组件更容易重用和测试。
**布尔模式**
当 props 设置为 true 时,`route.params` 将被设置为组件的 props。
**命名视图**
对于有命名视图的路由,你必须为每个命名视图定义 props 配置:
```javascript
const routes = [
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
```
**对象模式**
当 props 是一个对象时,它将原样设置为组件 props。当 props 是静态的时候很有用。
```javascript
const routes = [
{
path: '/promotion/from-newsletter',
component: Promotion,
props: { newsletterPopup: false }
}
]
```
**函数模式**
你可以创建一个返回 props 的函数。这允许你将参数转换为其他类型,将静态值与基于路由的值相结合等等。
```javascript
const routes = [
{
path: '/search',
component: SearchUser,
props: route => ({ query: route.query.q })
}
]
```
`URL /search?q=vue` 将传递 `{query: 'vue'}` 作为 props 传给 SearchUser 组件。
请尽可能保持 props 函数为无状态的,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props,请使用包装组件,这样 vue 才可以对状态变化做出反应。
<br>
 <div style="color: #8E7CC3;font-size:22px;font-weight:700">小测试:</div>
根据上方资料,以下关于路由组件传参的说法不正确的是?<br/><br/>
下列关于路由组件传参的说法不正确的是?<br/><br/>
## 答案
当 props 是一个对象时,它将原样设置为组件 props。当 props 不是静态的时候很有用。
当 props 是一个对象时,它将原样设置为组件 props。当 props 静态的时候很有用。
## 选项
### A
可以创建一个返回 props 的函数。将参数转换为其他类型,将静态值与基于路由的值相结合
你可以创建一个返回 props 的函数。这允许你将参数转换为其他类型,将静态值与基于路由的值相结合等等
### B
对于有命名视图的路由,你必须为每个命名视图定义 props 配置
请尽可能保持 props 函数为无状态的,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props,请使用包装组件,这样 vue 才可以对状态变化做出反应。
### C
......
# 路由重定向和别名
 <div style="color: pink;font-size:22px;font-weight:700">小常识:</div>
<br>
**重定向**
重定向也是通过 routes 配置来完成,下面例子是从 `/home` 重定向到 `/`
```javascript
const routes = [{ path: '/home', redirect: '/' }]
```
重定向的目标也可以是一个命名的路由:
```javascript
const routes = [{ path: '/home', redirect: { name: 'homepage' } }]
```
甚至是一个方法,动态返回重定向目标:
```javascript
const routes = [
{
// /search/screens -> /search?q=screens
path: '/search/:searchText',
redirect: to => {
// 方法接收目标路由作为参数
// return 重定向的字符串路径/路径对象
return { path: '/search', query: { q: to.params.searchText } }
},
},
{
path: '/search',
// ...
},
]
```
请注意,导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。在上面的例子中,在 /home 路由中添加 beforeEnter 守卫不会有任何效果。
在写 redirect 的时候,可以省略 component 配置,因为它从来没有被直接访问过,所以没有组件要渲染。唯一的例外是嵌套路由:如果一个路由记录有 children 和 redirect 属性,它也应该有 component 属性。
**相对重定向**
也可以重定向到相对位置:
```javascript
const routes = [
{
path: '/users/:id/posts',
redirect: to => {
// 方法接收目标路由作为参数
// return 重定向的字符串路径/路径对象
},
},
]
```
**别名**
重定向是指当用户访问 `/home` 时,URL 会被 `/` 替换,然后匹配成 `/`。那么什么是别名呢?
`/` 别名为 `/home`,意味着当用户访问 /home 时,URL 仍然是 `/home`,但会被匹配为用户正在访问 /。
上面对应的路由配置为:
```javascript
const routes = [{ path: '/', component: Homepage, alias: '/home' }]
```
通过别名,你可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。使别名以 / 开头,以使嵌套路径中的路径成为绝对路径。你甚至可以将两者结合起来,用一个数组提供多个别名:
```javascript
const routes = [
{
path: '/users',
component: UsersLayout,
children: [
// 为这 3 个 URL 呈现 UserList
// - /users
// - /users/list
// - /people
{ path: '', component: UserList, alias: ['/people', 'list'] },
],
},
]
```
如果你的路由有参数,请确保在任何绝对别名中包含它们:
```javascript
const routes = [
{
path: '/users/:id',
component: UsersByIdLayout,
children: [
// 为这 3 个 URL 呈现 UserDetails
// - /users/24
// - /users/24/profile
// - /24
{ path: 'profile', component: UserDetails, alias: ['/:id', ''] },
],
},
]
```
关于 SEO 的注意事项: 使用别名时,一定要定义规范链接.
<br>
 <div style="color: #8E7CC3;font-size:22px;font-weight:700">小测试:</div>
根据上方资料,以下关于路由重定向的说法不正确的是?<br/><br/>
下列关于路由重定向的说法不正确的是?<br/><br/>
## 答案
重定向不可以使用相对位置
重定向暂不支持重定向到相对位置
## 选项
### A
利用redirect进行重定向
利用redirect可以进行重定向,重定向也是通过 routes 配置来完成。
### B
在写 redirect 的时候,可以省略 component 配置
在写 redirect 的时候,可以省略 component 配置,因为它从来没有被直接访问过,所以没有组件要渲染。唯一的例外是嵌套路由:如果一个路由记录有 children 和 redirect 属性,它也应该有 component 属性。
### C
使用 alias 进行别名的设置
通过alias设置别名,你可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。
# 路由模式
 <div style="color: pink;font-size:22px;font-weight:700">小常识:</div>
<br>
**hash模式**
vue-router默认的是hash模式.
hash模式,是指url尾巴后的#号以及后面的字符.hash也被称为锚点,本身是用来做页面定位的.
hash虽然出现在url中,但不会被包括在http请求中,对后端完全没有影响,因此改变hash值不会重新加载页面
**history模式**
history模主要是通过history Api的pushState()和replaceState()两个方法来实现的.pushState()可以改变url地址且不会发送请求,replaceState()可以读取历史记录栈,还可以对浏览器记录进行修改
以上两个方法可以修改历史状态,下面三个方法可以切换(定位)历史状态
```javascript
history.go(-2);//后退两次
history.go(2);//前进两次
history.back(); //后退
hsitory.forward(); //前进
```
**abstract模式**
适用于所有JavaScript环境,例如服务器端使用Node.js。如果没有浏览器API,路由器将自动被强制进入此模式。
<br>
 <div style="color: #8E7CC3;font-size:22px;font-weight:700">小测试:</div>
根据上方小常识,以下关于路由模式的说法不正确的是?<br/><br/>
## 答案
路由有两种模式分别是hash模式和history模式
hash模式最大的优点就是对于 SEO 非常友好。
## 选项
### A
使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载
在创建路由器实例时,history 配置允许我们在不同的历史模式中进行选择。
### B
hash模式,会去掉路径中的 “#”
在hash模式中`#`后面 hash 值的变化,并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。
### C
history模式包括back、forward、go三个方法
history模式包括back、forward、go三个方法对应浏览器的前进,后退,跳转操作。
# 前置路由守卫
 <div style="color: pink;font-size:22px;font-weight:700">小常识:</div>
<br>
你可以使用 router.beforeEach 注册一个全局前置守卫:
```javascript
const router = createRouter({ ... })
router.beforeEach((to, from) => {
// ...
// 返回 false 以取消导航
return false
})
```
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。
每个守卫方法接收两个参数:
to: 即将要进入的目标 用一种标准化的方式
from: 当前导航正要离开的路由 用一种标准化的方式
可以返回的值如下:
false: 取消当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
一个路由地址: 通过一个路由地址跳转到一个不同的地址,就像你调用 `router.push()` 一样,你可以设置诸如 `replace: true``name: 'home'` 之类的配置。当前的导航被中断,然后进行一个新的导航,就和 from 一样。
如果遇到了意料之外的情况,可能会抛出一个 Error。这会取消导航并且调用 router.onError() 注册过的回调。
如果什么都没有,undefined 或返回 true,则导航是有效的,并调用下一个导航守卫
以上所有都同 async 函数 和 Promise 工作方式一样:
```javascript
router.beforeEach(async (to, from) => {
// canUserAccess() 返回 `true` 或 `false`
return await canUserAccess(to)
})
```
**可选的第三个参数 next**
在之前的 Vue Router 版本中,也是可以使用 第三个参数 next 的。这是一个常见的错误来源,可以通过 RFC 来消除错误。然而,它仍然是被支持的,这意味着你可以向任何导航守卫传递第三个参数。在这种情况下,确保 next 在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错。这里有一个在用户未能验证身份时重定向到/login的错误用例:
```javascript
// BAD
router.beforeEach((to, from, next) => {
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
// 如果用户未能验证身份,则 `next` 会被调用两次
next()
})
```
下面是正确的版本:
```javascript
// GOOD
router.beforeEach((to, from, next) => {
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
else next()
})
```
**全局解析守卫**
你可以用 `router.beforeResolve` 注册一个全局守卫。这和 `router.beforeEach` 类似,因为它在 每次导航时都会触发,但是确保在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被正确调用。这里有一个例子,确保用户可以访问自定义 meta 属性 requiresCamera 的路由:
```javascript
router.beforeResolve(async to => {
if (to.meta.requiresCamera) {
try {
await askForCameraPermission()
} catch (error) {
if (error instanceof NotAllowedError) {
// ... 处理错误,然后取消导航
return false
} else {
// 意料之外的错误,取消导航并把错误传给全局处理器
throw error
}
}
}
})
```
`router.beforeResolve` 是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。
<br>
 <div style="color: #8E7CC3;font-size:22px;font-weight:700">小测试:</div>
根据上方小常识,以下关于前置路由守卫的说法不正确的是?<br/><br/>
下列关于前置路由守卫的说法不正确的是?<br/><br/>
## 答案
守卫是同步解析执行
守卫是同步解析执行
## 选项
### A
在路由配置中添加meta属性,属性为自定义,用于守卫判断
可以通过 router.beforeEach 注册一个全局前置守卫。
### B
router.beforeEach 接收三个参数
router.beforeEach 可接收三个参数,to、from、next。
### C
当一个导航触发时,全局前置守卫按照创建顺序调用
当一个导航触发时,全局前置守卫按照创建顺序调用
\ No newline at end of file
# 后置路由守卫
 <div style="color: pink;font-size:22px;font-weight:700">小常识:</div>
<br>
**全局后置钩子**
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
```javascript
router.afterEach((to, from) => {
sendToAnalytics(to.fullPath)
})
```
它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。
它们也反映了 navigation failures 作为第三个参数:
```javascript
router.afterEach((to, from, failure) => {
if (!failure) sendToAnalytics(to.fullPath)
})
```
**完整的导航解析流程**
导航被触发。
在失活的组件里调用 beforeRouteLeave 守卫。
调用全局的 beforeEach 守卫。
在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
在路由配置里调用 beforeEnter。
解析异步路由组件。
在被激活的组件里调用 beforeRouteEnter。
调用全局的 beforeResolve 守卫(2.5+)。
导航被确认。
调用全局的 afterEach 钩子。
触发 DOM 更新。
调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
<br>
 <div style="color: #8E7CC3;font-size:22px;font-weight:700">小测试:</div>
根据上方资料,以下关于后置路由守卫的说法不正确的是?<br/><br/>
下列关于后置路由守卫的说法不正确的是?<br/><br/>
## 答案
router.afterEach 接受next参数
同路由前置守卫相同 router.afterEach 也可接收三个参数,to、from、next。
## 选项
### A
不会改变导航本身
router.afterEach 不会改变导航本身。
### B
接受navigation failures 作为第三个参数
接受 navigation failures 作为 router.afterEach 的参数。
### C
后置路由守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中
我们可以在 router.afterEach 中进行分析、更改页面标题、声明页面等辅助功能。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册