什么是Vue-Router?
Vue路由器是Vue.js的官方路由器,它与Vue.js核心深度集成,使用Vue轻松构建单页应用程序变得轻而易举。功能包括:
嵌套路线映射
动态路由
模块化,基于组件的路由器配置
路由参数,查询,通配符
查看由Vue.js过渡系统提供动力的过渡效果
细粒度的导航控制
带有自动活动CSS类的链接
HTML5历史记录模式或哈希模式
可自定义的滚动行为
网址的正确编码
路由的核心:改变Url,但页面不进行整体刷新 ,路由理解为指向
路由表,是一个映射表,一个路由就是一组映射关系。
形式: key : value key:表示路由 value:可为function(后台路由)或为 Component(组件)
安装:
直接下载 / CDN#
https://unpkg.com/vue-router@4
Unpkg.com 提供了基于 npm 的 CDN 链接。上述链接将始终指向 npm 上的最新版本。 你也可以通过像 https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js 这样的 URL 来使用特定的版本或 Tag。
npm
npm install vue-router@4
yarn
yarn add vue-router@4
安装成功后,会在package.json 中显示出来
使用 例子:
一、创建一个文件夹router 新建一个js文件来 进行路由集中管理
在新建一个views来存储组件
组件代码:
<template><div>这是Login组件</div>
</template>
app.vue首页
注意:
router-link#
请注意,我们没有使用常规的 a 标签,而是使用一个自定义组件 router-link 来创建链接。这使得 Vue Router 可以在不重新加载页面的情况下更改 URL,处理 URL 的生成以及编码。我们将在后面看到如何从这些功能中获益。
router-view#
router-view 将显示与 url 对应的组件。你可以把它放在任何地方,以适应你的布局。
<script setup></script><template><h1>Hello App!</h1><p><!--使用 router-link 组件进行导航 --><!--通过传递 `to` 来指定链接 --><!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签--><router-link to="/Login">Go to Home</router-link></p><!-- 路由出口 --><!-- 路由匹配到的组件将渲染在这里 --><router-view></router-view>
</template><style></style>
在路由js进行配置
import {createRouter,createWebHashHistory } from 'vue-router'// 1. 定义路由组件.
// 也可以从其他文件导入
import Login from '../views/Login.vue'// 2. 定义一些路由
// 每个路由都需要映射到一个组件。
// 我们后面再讨论嵌套路由。
const routes = [{ path: '/Login', component: Login },
]// 3. 创建路由实例并传递 `routes` 配置
// 你可以在这里输入更多的配置,但我们在这里
// 暂时保持简单
const router = createRouter({// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。history: createWebHashHistory(),routes, // `routes: routes` 的缩写
})//导出router
export default router;
在main.js 进行配置
vue-router带参的动态路由配置
新建一个路由
app.vue
如果想要这个参数显示出来要使用 $route
看看$route 这个里面包含着什么
可以看出从里面取得了链接等信息
在看看在组合api setup里怎么获取 通过 import { useRoute } from 'vue-router'
<template><div>这是首页</div>
</template>
<script setup>import { useRoute } from 'vue-router'console.log(useRoute())
</script>
正则传递参数 指定
嵌套路由
在想要在嵌套的路由上加上 children
通过js跳转页面
导航到不同的位置#
注意:在 Vue 实例中,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push。
想要导航到不同的 URL,可以使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。
当你点击 <router-link> 时,内部会调用这个方法,所以点击 <router-link :to="..."> 相当于调用 router.push(...) :
声明式 | 编程式 |
<router-link :to="..."> | router.push(...) |
该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:
// 字符串路径
router.push('/users/eduardo')// 带有路径的对象
router.push({ path: '/users/eduardo' })// 命名的路由,并加上参数,让路由建立 url 需要给路由配置 添加一个name 属性后才可以指定name
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' })
替换页面以及历史堆栈中前进和后退
替换当前位置#
它的作用类似于 router.push,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样——它取代了当前的条目。
声明式 | 编程式 |
<router-link :to="..." replace> | router.replace(...) |
也可以直接在传递给 router.push 的 routeLocation 中增加一个属性 replace: true :
js
router.push({ path: '/home', replace: true })//
相当于router.replace({ path: '/home' })
横跨历史#
在 Vue School 上观看免费视频课程
该方法采用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于 window.history.go(n)。
例子
js
// 向前移动一条记录,与 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 )都能始终正常工作。
命名视图
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。
html
<router-view class="view left-sidebar" name="LeftSidebar">
</router-view><router-view class="view main-content"></router-view>
<router-view class="view right-sidebar" name="RightSidebar"></router-view>
一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):
const router = createRouter({history: createWebHashHistory(),routes: [{path: '/',components: {default: Home,// LeftSidebar: LeftSidebar 的缩写LeftSidebar,// 它们与 `<router-view>` 上的 `name` 属性匹配RightSidebar,},},],
})
页面通过 <router-view name="" /> 来展示组件内容
<!-- UserSettings.vue -->
<div><h1>User Settings</h1><NavBar /><router-view /><router-view name="helper" />
</div>
重定向和别名
重定向也是通过 routes 配置来完成,下面例子是从 /home 重定向到 /:
js
const routes = [{ path: '/home', redirect: '/' }]
重定向的目标也可以是一个命名的路由:
js
const routes = [{ path: '/home', redirect: { name: 'homepage' } }]
甚至是一个方法,动态返回重定向目标:
js
const routes = [{// /search/screens -> /search?q=screenspath: '/search/:searchText',redirect: to => {// 方法接收目标路由作为参数// return 重定向的字符串路径/路径对象return { path: '/search', query: { q: to.params.searchText } }},},{path: '/search',// ...},
]
别名# alias 属性(也可以通过这个属性访问)
重定向是指当用户访问 /home 时,URL 会被 / 替换,然后匹配成 /。那么什么是别名呢?
将 / 别名为 /home,意味着当用户访问 /home 时,URL 仍然是 /home,但会被匹配为用户正在访问 /。
上面对应的路由配置为:
const routes = [{ path: '/', component: Homepage, alias: '/home' }]
通过别名,你可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。使别名以 / 开头,以使嵌套路径中的路径成为绝对路径。你甚至可以将两者结合起来,用一个数组提供多个别名:
const routes = [{path: '/users',component: UsersLayout,children: [// 为这 3 个 URL 呈现 UserList// - /users// - /users/list// - /people{ path: '', component: UserList, alias: ['/people', '/list'] },],},
]
如果你的路由有参数,请确保在任何绝对别名中包含它们: alias: ['/:id', '']
const routes = [{path: '/users/:id',component: UsersByIdLayout,children: [// 为这 3 个 URL 呈现 UserDetails// - /users/24// - /users/24/profile// - /24{ path: 'profile', component: UserDetails, alias: ['/:id', ''] },],},
]
将 props 传递给路由组件#
在 Vue School 上观看免费视频课程
在你的组件中使用 $route 会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。虽然这不一定是件坏事,但我们可以通过 props 配置来解除这种行为:
我们可以将下面的代码
const User = {template: '<div>User {{ $route.params.id }}</div>'
}
const routes = [{ path: '/user/:id', component: User }]
对于有命名视图的路由,你必须为每个命名视图定义 props 配置:
js
const routes = [{path: '/user/:id',components: { default: User, sidebar: Sidebar },props: { default: true, sidebar: false }}
]
页面获取通过:
在组件api里直接接受通过:
导航守卫
1、什么是导航守卫?
正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。
如我要进入首页页面,我要判断我是否登录了 如果登录了 才能进入首页
2、配置
1、全局前置守卫#
你可以使用 router.beforeEach 注册一个全局前置守卫:
// 全局导航守卫
//next相当于一个关卡通行证的意思 to是要去的页面 from 为什么地方来的
router.beforeEach((to,from,next)=>{})
2、在需要使用的路由上添加关卡
{ path: '/index/:username',component: Index ,// 守卫路由配置beforeEnter:(to,from,next)=>{console.log(to);console.log(from);// 模拟tokensif(123==123214233){next()}}}, //带参
组件内的守卫#
最 后,你可以在路由组件内直接定义路由导航守卫(传递给路由配置的)
可用的配置 API#
你可以为路由组件添加以下配置:
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
const UserDetails = {template: `...`,beforeRouteEnter(to, from) {// 在渲染该组件的对应路由被验证前调用// 不能获取组件实例 `this` !// 因为当守卫执行时,组件实例还没被创建!},beforeRouteUpdate(to, from) {// 在当前路由改变,但是该组件被复用时调用// 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,// 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。// 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`},beforeRouteLeave(to, from) {// 在导航离开渲染该组件的对应路由时调用// 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`},
}
beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next 来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数:
js
beforeRouteEnter (to, from, next)
{ next(vm => { // 通过 `vm` 访问组件实例 })
}
路由懒加载
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。
Vue Router 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入:
通俗易懂的说就是用到时在加载
使用:
将Componet 以函数的形式来写:
// 将
// import UserDetails from './views/UserDetails.vue'
// 替换成
const UserDetails = () => import('./views/UserDetails.vue')const router = createRouter({// ...routes: [{ path: '/users/:id', component: UserDetails }],
})
如何进行状态管理
新建一个js来进行全局参数的配置
根组件vue通过provide注入
引入 store
子组件通过 inject来获取