diff --git "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/1.vue-router\346\230\257\344\273\200\344\271\210\357\274\237/exercises.md" "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/1.vue-router\346\230\257\344\273\200\344\271\210\357\274\237/exercises.md" index 81c650161a62d9b58ebfb1594c8cdb25935497cd..eb590018beee9c60699ee4e67865a6527e39a306 100644 --- "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/1.vue-router\346\230\257\344\273\200\344\271\210\357\274\237/exercises.md" +++ "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/1.vue-router\346\230\257\344\273\200\344\271\210\357\274\237/exercises.md" @@ -1,56 +1,21 @@ # vue-router是什么? - 
小常识:
-
- -**概念** -路由的本质就是一种对应关系,比如说我们在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 的正确编码 -
- - 
小测试:
- -根据上方资料,以下对于vue-router说法不正确的是?

+以下对于vue-router说法不正确的是?

## 答案 -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的常用的模式。 diff --git "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/2.\350\267\257\347\224\261\345\256\211\350\243\205/exercises.md" "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/2.\350\267\257\347\224\261\345\256\211\350\243\205/exercises.md" index eb57a8684fcc18720b3924804d440bfa96454476..0bb3d659f23d78ec9547a071360bbdb9a5a7d850 100644 --- "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/2.\350\267\257\347\224\261\345\256\211\350\243\205/exercises.md" +++ "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/2.\350\267\257\347\224\261\345\256\211\350\243\205/exercises.md" @@ -1,53 +1,21 @@ # 路由安装 - - 
小常识:
-
- -**直接下载 / 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 -``` - -
- - 
小测试:
- -根据上方资料,以下关于vue-router的安装说法不正确的是?

+以下关于vue-router的安装说法不正确的是?

## 答案 -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进行安装 diff --git "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/3.\347\274\226\347\250\213\345\274\217\347\232\204\345\257\274\350\210\252/exercises.md" "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/3.\347\274\226\347\250\213\345\274\217\347\232\204\345\257\274\350\210\252/exercises.md" index d836bd7779e9d12500becb6b674ec30e7ca053ed..7323d206ce2ba223cd7d0ba7d1c7686cb2fbe73a 100644 --- "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/3.\347\274\226\347\250\213\345\274\217\347\232\204\345\257\274\350\210\252/exercises.md" +++ "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/3.\347\274\226\347\250\213\345\274\217\347\232\204\345\257\274\350\210\252/exercises.md" @@ -1,108 +1,5 @@ # 编程式的导航 - 
小常识:
-
- -**编程式导航** - -除了使用 `` 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。 - -**导航到不同的位置** - -注意:在 Vue 实例中,你可以通过 `$router` 访问路由实例。因此你可以调用 `this.$router.push`。 - -想要导航到不同的 URL,可以使用 `router.push` 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。 - -当你点击 `` 时,内部会调用这个方法,所以点击 `` 相当于调用 `router.push(...)` : - -|声明式 | 编程式 | -|--|--| -| `` | `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.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)`都能始终如一地工作。 - -
- - 
小测试:
观察下列编程式导航,描述不正确的是?

@@ -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.push(...) : diff --git "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/4.\345\212\250\346\200\201\350\267\257\347\224\261/exercises.md" "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/4.\345\212\250\346\200\201\350\267\257\347\224\261/exercises.md" index a68684c6916e609b1e744f7c3abce3a351c5d1af..68844eef87422be4dcc134acbb5d07a32725d279 100644 --- "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/4.\345\212\250\346\200\201\350\267\257\347\224\261/exercises.md" +++ "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/4.\345\212\250\346\200\201\350\267\257\347\224\261/exercises.md" @@ -1,130 +1,23 @@ # 动态路由 - 
小常识:
-
-**动态路由** -对路由的添加通常是通过 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():获取一个包含所有路由记录的数组。 -``` - -
- - 
小测试:
- -根据上方小常识,以下关于动态路由的说法不正确的是?

+下列关于动态路由的说法不正确的是?

## 答案 -路径参数不接受 正则表达式 +对路由的添加通常是通过 routes 选项来完成的,所以在应用程序已经运行的时候是不能支持路由的添加或删除的。 ## 选项 ### A -动态路由的路径参数 用冒号 : 表示 +在 Vue Router 中路径参数 用冒号 : 表示。当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来。 ### B -要对同一个组件中参数的变化做出响应的话,你可以简单地 watch $route 对象上的任意属性 +动态路由主要通过两个函数实现。router.addRoute() 和 router.removeRoute()。 ### C -当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来 +如果新增加的路由与当前位置相匹配,就需要你用 router.push() 或 router.replace() 来手动导航,才能显示该新路由。 diff --git "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/5.\350\267\257\347\224\261\347\273\204\344\273\266\344\274\240\345\217\202/exercises.md" "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/5.\350\267\257\347\224\261\347\273\204\344\273\266\344\274\240\345\217\202/exercises.md" index 47e61041aac131ded36c5defd08244e4ce749b23..11176e3b69806285df16e7c81f5eecb8374f135b 100644 --- "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/5.\350\267\257\347\224\261\347\273\204\344\273\266\344\274\240\345\217\202/exercises.md" +++ "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/5.\350\267\257\347\224\261\347\273\204\344\273\266\344\274\240\345\217\202/exercises.md" @@ -1,97 +1,21 @@ # 路由组件传参 - 
小常识:
-
-**将 props 传递给路由组件** -在你的组件中使用 `$route` 会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。虽然这不一定是件坏事,但我们可以通过 props 配置来解除这种行为: - -我们可以将下面的代码 - -```javascript -const User = { - template: '
User {{ $route.params.id }}
' -} -const routes = [{ path: '/user/:id', component: User }] -``` - -替换成 - -```javascript -const User = { - props: ['id'], - template: '
User {{ id }}
' -} -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 才可以对状态变化做出反应。 - -
- - 
小测试:
- -根据上方资料,以下关于路由组件传参的说法不正确的是?

+下列关于路由组件传参的说法不正确的是?

## 答案 -当 props 是一个对象时,它将原样设置为组件 props。当 props 不是静态的时候很有用。 +当 props 是一个对象时,它将原样设置为组件 props。当 props 非静态的时候很有用。 ## 选项 ### A -可以创建一个返回 props 的函数。将参数转换为其他类型,将静态值与基于路由的值相结合。 +你可以创建一个返回 props 的函数。这允许你将参数转换为其他类型,将静态值与基于路由的值相结合等等。 ### B -对于有命名视图的路由,你必须为每个命名视图定义 props 配置 +请尽可能保持 props 函数为无状态的,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props,请使用包装组件,这样 vue 才可以对状态变化做出反应。 ### C diff --git "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/6.\350\267\257\347\224\261\351\207\215\345\256\232\345\220\221\345\222\214\345\210\253\345\220\215/exercises.md" "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/6.\350\267\257\347\224\261\351\207\215\345\256\232\345\220\221\345\222\214\345\210\253\345\220\215/exercises.md" index 513763cb12a8063df23b3d0c03a036b8a12b8370..8b18f4ebcdf4c26026703ae64eae72709590e302 100644 --- "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/6.\350\267\257\347\224\261\351\207\215\345\256\232\345\220\221\345\222\214\345\210\253\345\220\215/exercises.md" +++ "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/6.\350\267\257\347\224\261\351\207\215\345\256\232\345\220\221\345\222\214\345\210\253\345\220\215/exercises.md" @@ -1,129 +1,22 @@ # 路由重定向和别名 - 
小常识:
-
-**重定向** -重定向也是通过 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 的注意事项: 使用别名时,一定要定义规范链接. - -
- - 
小测试:
- -根据上方资料,以下关于路由重定向的说法不正确的是?

+下列关于路由重定向的说法不正确的是?

## 答案 -重定向不可以使用相对位置 +重定向暂不支持重定向到相对位置 ## 选项 ### A -利用redirect进行重定向 +利用redirect可以进行重定向,重定向也是通过 routes 配置来完成。 ### B -在写 redirect 的时候,可以省略 component 配置 +在写 redirect 的时候,可以省略 component 配置,因为它从来没有被直接访问过,所以没有组件要渲染。唯一的例外是嵌套路由:如果一个路由记录有 children 和 redirect 属性,它也应该有 component 属性。 ### C -使用 alias 进行别名的设置 +通过alias设置别名,你可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。 diff --git "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/7.\350\267\257\347\224\261\346\250\241\345\274\217/exercises.md" "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/7.\350\267\257\347\224\261\346\250\241\345\274\217/exercises.md" index 44e00f984d91d3be83a82b5d5e144ae1b6d5b954..bd5e9e9931acbcc4ad868ab6176ce06e3ad587fd 100644 --- "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/7.\350\267\257\347\224\261\346\250\241\345\274\217/exercises.md" +++ "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/7.\350\267\257\347\224\261\346\250\241\345\274\217/exercises.md" @@ -1,49 +1,23 @@ # 路由模式 - 
小常识:
-
-**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,路由器将自动被强制进入此模式。 - -
- - 
小测试:
根据上方小常识,以下关于路由模式的说法不正确的是?

## 答案 -路由有两种模式分别是hash模式和history模式 +hash模式最大的优点就是对于 SEO 非常友好。 ## 选项 ### A -使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载 +在创建路由器实例时,history 配置允许我们在不同的历史模式中进行选择。 ### B -hash模式,会去掉路径中的 “#” +在hash模式中`#`后面 hash 值的变化,并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。 ### C -history模式包括back、forward、go三个方法 +history模式包括back、forward、go三个方法对应浏览器的前进,后退,跳转操作。 diff --git "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/8.\345\211\215\347\275\256\350\267\257\347\224\261\345\256\210\345\215\253/exercises.md" "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/8.\345\211\215\347\275\256\350\267\257\347\224\261\345\256\210\345\215\253/exercises.md" index 5fa766d7e83e22d1447f1a54a18457908f5f8cba..328aa707d79d7e4d9a7a95542fdc5d3d5ac7d39f 100644 --- "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/8.\345\211\215\347\275\256\350\267\257\347\224\261\345\256\210\345\215\253/exercises.md" +++ "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/8.\345\211\215\347\275\256\350\267\257\347\224\261\345\256\210\345\215\253/exercises.md" @@ -1,108 +1,22 @@ # 前置路由守卫 - 
小常识:
-
-你可以使用 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` 是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。 - -
- - 
小测试:
- -根据上方小常识,以下关于前置路由守卫的说法不正确的是?

+下列关于前置路由守卫的说法不正确的是?

## 答案 -守卫是同步解析执行 +守卫是同步解析执行。 ## 选项 ### A -在路由配置中添加meta属性,属性为自定义,用于守卫判断 +可以通过 router.beforeEach 注册一个全局前置守卫。 ### B -router.beforeEach 接收三个参数 +router.beforeEach 可接收三个参数,to、from、next。 ### C -当一个导航触发时,全局前置守卫按照创建顺序调用 +当一个导航触发时,全局前置守卫按照创建顺序调用。 \ No newline at end of file diff --git "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/9.\345\220\216\347\275\256\350\267\257\347\224\261\345\256\210\345\215\253/exercises.md" "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/9.\345\220\216\347\275\256\350\267\257\347\224\261\345\256\210\345\215\253/exercises.md" index 2e069d56cf380eed202f8f568896a741f139122f..98b1f75fe9d099c390af243f929708cbf0171611 100644 --- "a/data/2.Vue\344\270\255\351\230\266/2.Vue-router/9.\345\220\216\347\275\256\350\267\257\347\224\261\345\256\210\345\215\253/exercises.md" +++ "b/data/2.Vue\344\270\255\351\230\266/2.Vue-router/9.\345\220\216\347\275\256\350\267\257\347\224\261\345\256\210\345\215\253/exercises.md" @@ -1,61 +1,22 @@ # 后置路由守卫 - 
小常识:
-
-**全局后置钩子** -你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 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 的回调函数,创建好的组件实例会作为回调函数的参数传入。 - -
- - 
小测试:
- - -根据上方资料,以下关于后置路由守卫的说法不正确的是?

+下列关于后置路由守卫的说法不正确的是?

## 答案 -router.afterEach 接受next参数 +同路由前置守卫相同 router.afterEach 也可接收三个参数,to、from、next。 ## 选项 ### A -不会改变导航本身 +router.afterEach 不会改变导航本身。 ### B -接受navigation failures 作为第三个参数 +接受 navigation failures 作为 router.afterEach 的参数。 ### C -后置路由守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中 +我们可以在 router.afterEach 中进行分析、更改页面标题、声明页面等辅助功能。