跳到主要内容

2.1-vue-router

Create by fall on 11 Apr 2021 Recently revised in:2022-09-01

路由中的两大对象

vue-router 是 vue 实现,控制路由的官方插件

其中有两大对象

$router 和 $route

下面来详细说说两者的不同:

$router表示的是全局路由对象

$router.push('login')
$router.push({path:'home'})
$router.push({name:'user',params:{id:12314}})
$router.push({ path: 'register', query: { plan: '123' }})
$router.go(-1) // 回退

$route 当前路由对象

$route.path
字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"。
$route.params
一个 key/value 对象,包含了 动态片段 和 全匹配片段,
如果没有路由参数,就是一个空对象。
$route.query
一个 key/value 对象,表示 URL 查询参数。
例如,对于路径 /foo?user=1,则有 $route.query.user == 1,
如果没有查询参数,则是个空对象。
$route.hash
当前路由的 hash 值 (不带 #) ,如果没有 hash 值,则为空字符串。锚点
$route.fullPath
完成解析后的 URL,包含查询参数和 hash 的完整路径。
$route.matched
数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
$route.name 当前路径名字
$route.meta 路由元信息

路由

路由执行顺序

  • 导航被触发。
  • 在失活的组件里调用 beforeRouteLeave 守卫。
  • 调用全局的 beforeEach 守卫。
  • 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  • 在路由配置里调用 beforeEnter。
  • 解析异步路由组件。
  • 在被激活的组件里调用 beforeRouteEnter。
  • 调用全局的 beforeResolve 守卫 (2.5+)。
  • 导航被确认。
  • 调用全局的 afterEach 钩子。
    • 触发 DOM 更新。
  • 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

路由守卫

全局守卫

  • router.beforeEach 全局前置守卫 进入路由之前
  • router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用
  • router.afterEach 全局后置钩子 进入路由之后
// main.js 入口文件
import router from './router'; // 引入路由
router.beforeEach((to, from, next) => {
next();
});
router.beforeResolve((to, from, next) => {
next();
});
router.afterEach((to, from) => {
console.log('afterEach 全局后置钩子');
});

参数:

  • to:表明前往的路由
  • from:表明从哪里来
  • next:表示进行接下来的内容,必须要进行调用,调用方式如下
    • next():进入下一个路由
    • next(false):取消进入下一个路由
    • next('path'):进入 path 路由,或者和 router.push 相同的参数

独享守卫

const routers = [
{
path:'/path',
component:()=>import('./Page.vue')
beforeEnter: (to, from, next) => {
// 参数用法什么的都一样,调用顺序在全局前置守卫后面,所以不会被全局守卫覆盖
// ...
}
}
]
  • beforeRouteEnter 进入路由前
  • beforeRouteUpdate (2.2) 路由复用同一个组件时
  • beforeRouteLeave 离开当前路由时
const route = {
beforeRouteEnter (to, from, next) {
// 在路由独享守卫后调用 不!能!获取组件实例 `this`,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用 可以访问组件实例 `this`
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用,可以访问组件实例 `this`
}
}

路由错误捕获

router.onError(err=>{
console.log(err)
})

路由

路由的本质就是 URL 的对应关系,分为前端路由后端路由

后端路由

根据用户不同的 URL 请求 ,返回不同的内容,服务器动态生成的页面,PHP这类的动态资源网页,大概是这样。

如果用户经常提交表单,会造成网页的频繁刷新,因此出现了ajax技术,实现局部刷新。ajax技术不支持浏览器的前进后退。即浏览器无法保存用户在网页的浏览状态,因此出现了SPA单页面开发技术。

后端路由的本质:URL 地址和服务器资源之间的关系

SPA:单页面应用程序,整个网站只有一个页面,内容通过ajax局部刷新实现,同时支持浏览器的前进后退功能。

前端路由

根据不同的用户事件,显示不同的内容。

每当用户触发一个事件后,会被路由监听到,路由会把这次请求分发给对应的事件处理函数,紧接着事件处理函数会渲染对应的内容,呈现给用户。(前端路由负责事件监听,触发事件后,通过事件函数渲染不同的内容

Vue路由

官网:https://next.router.vuejs.org/zh/introduction.html

包含功能:

支持HTML5历史模式和hash模式,支持嵌套路由,支持路由参数,支持编程式路由,支持命名式路由。

注:该文档是使用 Vue2 做的示例,所以,如果是 Vue3 的项目,尽量不要参考该代码。

路由的使用

这里的使用都是 .html 界面中路由的使用,不是 .vue 文件中路由的使用

<!-- 在引入vue.js 之后引入 vue-router.js -->
<div class='app'>
<router-link to="/home">Register</router-link>
<router-link to="/user">User</router-link>
<router-view></router-view>
<!-- 作为路由占位符 -->
</div>
<script>
const Home = {
template:`<h1>主页</h1>`
}
const User = {
template:`<h1>用户页面</h1>`
}
const router = new VueRouter({
routes:[
{path:'/home',component:Home},
{path:'/user',component:User}
]
})
const app = new Vue({
el:".app",
router:router,// 挂在实例对象
data:{}
})
</script>

嵌套路由

<div class='app'>
<router-link to="/home">Register</router-link>
<router-link to="/user">User</router-link>
<router-view></router-view>
<!-- 作为路由占位符 -->
</div>
<script>
const goudan = {
template:`<h2>狗蛋</h2>`
}
const mahua ={
template:`<h2>麻花</h2>`
}
const User = {
template:`
<div>
<h1>用户</h1>
<router-link to="/user/goudan">李狗蛋</router-link>
<router-link to="/user/mahua">李麻花</router-link>
<router-view></router-view>
</div>
`,
component:{}
}
const router = new VueRouter({
routes:[
{path:'/',redirect:'/home'},
{path:'/home',component:Home},
{path:'/user',component:User,children:[{
path:'/user/mahua',component:mahua
},{
path:'/user/goudan',component:goudan
}]}
]
})
const app = new Vue({
el:".app",
router:router,// 挂在实例对象
data:{
},
})
</script>

动态路由

动态路由是为了满足多个相似路径的路由的需要

<div class='app'>
<router-link to="/home">Register</router-link>
<router-link to="/user/12">User12</router-link>
<router-link to="/user/33">User33</router-link>
<router-link to="/user/62">User62</router-link>
<router-view></router-view>
</div>
<script>
const Home = {
template: `<h1>主页</h1>`
}
const theUser = {
template: `<h1>{{$route.params.name}}</h1>`
}
// theUser2 是利用动态路由匹配,props = true 后可以直接将 theUser 换成 theUser2,
const theUser2
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/home' },
{ path: '/home', component: Home },
{ path: '/user/:name', component: theUser ,props:true}
]
})
const app = new Vue({
el: ".app",
router: router,// 挂在实例对象
data: {},
})
</script>

命名路由

<router-view :to='{name:user,parames:{id:999}}'></router-view>
<!--需要为router内的函数设置一个值 -->

导航方式

声明式导航

利用<a href="#5566">链接</a> ,和<router-link></router-link>

编程式导航

调用JavaScript API来实现导航的方式,成为编程式导航

location.herf()

vue中的导航基本用法

this.$router.push('hash地址')
this.$router.go(n) // 填数字,可以前进或者后退n位
this.$router.push({path:'/home'})
this.$router.push({name:'/home',parames})

强制重定向

访问a地址的时候,强制用户跳转到地址c,从而展示特定的组件页面

route和router

通过 params 传值时,必须使用 name,而不是 path

route

表示当前路由中解析的信息,还有匹配到的 route records(路由记录)

路由信息功能
$route.path字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"。
$route.params一个对象,包含了 动态片段 和 全匹配片段,
如果没有路由参数,就是一个空对象。
$route.query一个对象,表示 URL的查询字符串。
例如,对于路径 /foo?user=1,则有 $route.query.user == 1
如果没有查询参数,则是个空对象。
$route.hash当前路由的 hash 值 (不带 #) ,如果没有 hash 值,则为空字符串。
$route.fullPath完成解析后的 URL,包含查询参数和 hash 的完整路径。
$route.matched数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
$route.name路径的名称
$route.meta路由元信息

router

全局的路由实例,是router构造方法的实例。

内部的实例

const router = new Router({
routes: [
{
path: "/",
name: "首页",
redirect: '/home'
},
{
path: '/login',
name: 'Login',
component: Login
},
{ path: '*', component: NotFoundComponent }
],
linkActiveClass: "active-router",
linkExactActiveClass: "exact-router"
})

路由的实例方法

// push方法其实和<router-link :to="...">是等同的。
// 字符串
this.$router.push('home')
// 对象
this.$router.push({ path: 'home' })
// 命名的路由
this.$router.push({ name: 'user', params: { userId: 123 }})
// 带查询参数,变成 /register?plan=123
this.$router.push({ path: 'register', query: { plan: '123' }})

路由守卫

路由守卫作用在router上

// 全局前置守卫
router.beforeEach(to,from,next){
console.log('to表示要前往的界面');
console.log(to);
console.log('from 表示从哪个页面过来');
console.log(from);
console.log('------------next----------');
console.log(next);
next(false)
// next(false) 中断当前的导航。
}

文章参考

作者连接
Ishmael丶Yokohttps://www.jianshu.com/p/fa0b5d919615
OBKoro1https://juejin.cn/post/6844903641866829838