Vue-router相关的知识点
Vue-router
- Vue-router 介绍(基本的使用)
- 脚手架里面如何使用
- hash 模式和 history 模式
- router-link 配置
- 嵌套路由
- 命名路由和命名视图
- 重定向和别名
- 编程式导航
- 动态路由
- 导航守卫
Vue-router 介绍(基本的使用)
vue-router 是 vue 技术栈(全家桶)里面的一员,它是官方给我们所提供的前端路由器。
在最早期的时候,是没有前端路由这么一个说法,以前只有后端路由。以前上网的时候,只要 url 一变化,就会向服务器发送请求。
但是现在,流行单页应用应用,其中最流行的方式就是改变一个 url 的 #(hash)后面的部分,这样可以做到 url 虽然发生了变化,但是不会向服务器发送请求。
所以说,这个时候,就需要一个前端路由了。通过前端路由来导航,决定 hash 后面的值的变化如何进行页面的导航。
接下来,我们来看一个 vue-router 的快速入门示例:
<body>
<div id="app">
<h1>欢迎学习 vue-router</h1>
<div>
<router-link to="/com1">内容1</router-link>
<router-link to="/com2">内容2</router-link>
<!-- 这里就是路由的出口,匹配上的组件会渲染到这个 router-view 这个位置 -->
<router-view></router-view>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.js"></script>
<script>
// 1. 创建 2 个组件
const com1 = {
template : `<div>这是组件1</div>`
}
const com2 = {
template : `<div>这是组件2</div>`
}
// 2. 配置我们的路由的路径
const routes = [{
path : '/com1',
component : com1
},{
path : '/com2',
component : com2
}];
// 3. 创建 router 实例
const router = new VueRouter({
routes
})
// 至此,我们的路由就创建好了,并里面指定了路由该如何跳转
// 最后一步,就是需要将这个路由挂载到我们的 vue 实例上面
const app = new Vue({
router
}).$mount('#app'); // 以渲染函数的方式进行挂载
</script>
</body>
脚手架里面如何使用
在脚手架中使用 vue-router 的方法基本上和上面的快速入门示例相同。
首先,我们会有一个专门的 router/index.js 来书写我们的路由。里面的代码仍然是:
- 配置路由如何进行导航
- 实例话一个 router 路由的实例(里面进行相应的配置)
- 导出这个 router 实例
- 在 vue 实例中对 router 实例进行挂载
在组件中,我们可以通过 this.router 可以获取到 vue-router 实例。
例如:
mounted() {
console.log("当前的路由器:", this.$route);
console.log("整个路由器:", this.$router);
}
hash 模式和 history 模式
hash 模式就是我们最早使用单页应用时候的形式,一个 url 里面会有一个 #,写出来的样子大致如下:
http:localhost:3000/#/stu
可以看到,使用 hash 模式,路由里面存在一个 #,不是很美观,html 5 推出了 history 相关的 api,利用 history 相关的 api,我们可以将路由修改为历史模式,从而去除了 # 号。
http:localhost:3000/stu
在 vue-router 中,要配置 hash 模式还是 history 模式的方法非常简单,在创建 vue-router 实例的时候,有一个 mode 选项,hash 对应 hash 模式,history 对应 history 模式。
const router = new VueRouter({
mode: 'history', // 配置路由究竟是 hash 模式还是 history 模式
base: process.env.BASE_URL,
routes
})
router-link 相关配置
router-link 是链接,可以导航到对应的组件(是在 router 文件里面配置的)。
首先,我们来看一下 router-link 在浏览器中的渲染是什么。
在浏览器中,router-link 会被渲染成 a 标签。
动态绑定路由的跳转,其实就是之前学过的知识,示例如下:
// tempalte
<router-link :to="test1">Home</router-link> |
<router-link :to="test2">About</router-link>
// js
<script>
export default {
data(){
return {
test1 : '/',
test2 : '/about'
}
}
}
</script>
通过设置 tag 值来决定最终渲染成什么标签(默认是 a 标签)
示例如下:
<router-link :to="test1" tag='p'>Home</router-link>
可以设置 router-link 的激活样式
首先,在创建 vue-router 实例的地方,添加 linkActiveClass 的键名,后面对应要应用的样式,如下:
// /src/router/index.js
const router = new VueRouter({
linkActiveClass : 'activeClass', // 这里就是设置 router-link 激活的样式
mode: 'history', // 配置路由究竟是 hash 模式还是 history 模式
base: process.env.BASE_URL,
routes
})
接下来,需要在 router-link 所在的组件位置书写相应的css样式,如下:
// App.vue
<style lang="scss">
.activeClass{
font-size: 32px;
color: red;
}
</style>
还可以设置 router-view 的公共样式。
首先,需要在 router-view 里面书写一个类名,例如:
<router-view class='viewClass'/>
接下来在有 router-view 的组件的 style 里面书写对应的样式即可。如下:
.viewClass {
color: skyblue;
}
我们还可以更改触发router 的事件,默认是点击事件。要更改的话,直接在router-link上面添加 event 属性,属性值用来指定具体的事件即可。例如:
<router-link :to="test2" event="mouseover">About</router-link>
嵌套路由
在实际业务,非常常见的一个需求,就是路由的嵌套。
首先,在 router/index.js 里面进行嵌套路由的配置,嵌套路由,需要使用到 children 这个配置项。
具体配置如下:
{
path: '/user',
component : User,
children : [{
path : 'one',
component : One
},{
path : 'two',
component : Two
}] // 这里面就是用来配置 user 的子路由
}
接下来,既然需要 one 和 two 这两个组件,那么,就需要创建这么两个对应的组件
// one 组件如下,two 组件和 one 一样
<template>
<div>
this is one component
</div>
</template>
接下来,就需要在 User 组件里面,也设置 router-link 和 router-view,代码如下:
<template>
<div>
这是 User 组件
<router-link to='/user/one'>one</router-link>
<router-link to='/user/two'>two</router-link>
<router-view></router-view>
</div>
</template>
命名路由和命名视图
上面我们介绍了嵌套的路由,那么在实际的开发中,可能就会存在嵌套的层数比较多。那么我们在进行导航的,可能就会存在如下的情况:
<router-link to='user/one/two/three/four'>xxx</router-link>
这个时候,我们就可以使用命名路由的方式。
用法很简单,首先,需要给配置的组件一个 name 属性,如下:
...
children : [{
path : 'one',
name : 'one', // 给该配置的组件一个 name 属性
component : One
},{
...
接下来,在 router-link 中,就可以使用对象的形式来进行访问:
...
<router-link :to='{name:"one"}'>one</router-link>
...
有些时候,我们想要展示多个视图。这个时候,我们可以设置多个router-view,并且给router-view命名,加上 name 属性。
如下:
<router-view class='viewClass' name="sider"/>
<router-view class='viewClass' name="default"/>
<router-view class='viewClass' name="home"/>
接下来,既然有了 3 个 router-view,那么在进行路由配置的时候,就需要指定每一个router-view渲染哪一个组件,配置如下:
{
path: '/home',
name: 'Home',
components: {
default : User,
sider : One,
home : Two
}
}
重定向和别名
所谓重定向,就是从一个路由跳转到另外一个路由。
在vue-router中,设置重定向的方法很简单,直接在routes里面进行配置即可。
...
{
path: '/home',
name: 'Home',
redirect : '/about', // 重定向到 about 页面
components: {
default : Home,
sider : One,
home : Two
}
},
...
所谓别名,就是可以给路由的配置取一个小名。示例如下:
{
path: '/about',
name: 'About',
alias : '/abc', // 给 about 取了一个别名
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},
访问的时候,就正常像访问路由一样访问即可,如下:
<router-link to="/abc">About</router-link>
编程式导航
前面我们所书写的导航的方式,叫做声明式导航。
所谓编程式导航,就是使用方法来进行跳转。例如:
// template
<button @click='gotoAbout'>go to about</button>
// js
gotoAbout(){
// 导航到 about 页面
// 页面栈
// this.$router.push('/about'); // 推入一个新的页面
this.$router.replace('/about'); // 替换一个页面组件
// 除此之外,还有诸如 back、forward、go 等方法
}
动态路由
有些时候,我们在渲染某一个组件的时候,可能会有的需求是,渲染的组件是同一个组件,但是根据传入的状态值不同,渲染的内容不一样。
http://localhost:3000/stu
对应就应该是 stu 学生组件,这个组件是显示学生信息的。根据学生 id 的不同,学生的信息是完全不同的。
http://localhost:3000/stu/1
http://localhost:3000/stu/2
那么,在跳转到 stu 这个组件的时候,我们就需要拿到后面的动态参数,然后决定渲染哪一个信息。
具体示例如下:
首先,需要在路由配置的地方,打开动态参数,如下:
...
{
path : '/stu/:id', // 代表有一个的动态参数,如果需要动态参数可选,那么可以加一个 ?,path : '/stu/:id?'
component : Stu
}
...
接下来,要渲染的组件都是 stu,那么我们就需要在 stu 组件里面首先获取到传递过来的 id,获取到之后,渲染出对应 id 的学生信息。代码如下:
// 第一次渲染 User 组件时获取当前的路由地址
created() {
let id = this.$route.params.id;
console.log("created id", id);
this.stuInfo = stus.filter(item => {
return item.id == id;
});
console.log(this.stuInfo,'aaa')
},
// 之后对路由进行监听,如果后面的参数发生变化,会触发 $route 方法
// to 为新的路由,from 为旧的路由
watch: {
$route(to, from) {
let id = to.params.id;
console.log("watch id", id);
this.stuInfo = stus.filter(item => {
return item.id == id;
});
}
}
获取动态路由的后面的参数的时候,还可以使用 props 来进行获取。
具体步骤,首先需要在路由配置里面,开启 props,如下:
{
path : '/stu/:id', // 代表有一个的动态参数,如果需要动态参数可选,那么可以加一个 ?,path : '/stu/:id?'
component : Stu,
props : true // 开启 props,也就是说,回头组件在获取 id 的时候,可以通过 props 来获取
}
接下来,在组件中,就可以通过 this.id 的方式来进行 id 的获取。
props :['id'], // 通过 props 获取到 id
// 第一次渲染 User 组件时获取当前的路由地址
created() {
let id = this.id;
console.log("created id", id);
this.stuInfo = stus.filter(item => {
return item.id == id;
});
console.log(this.stuInfo,'aaa')
},
// 之后对路由进行监听,如果后面的参数发生变化,会触发 $route 方法
// to 为新的路由,from 为旧的路由
watch: {
$route() {
let id = this.id;
console.log("watch id", id);
this.stuInfo = stus.filter(item => {
return item.id == id;
});
}
}
导航守卫
所谓导航守卫,就是只一个路由的一系列生命周期过程。当我们从一个路由导航到另外一个路由的时候,会经历一系列的生命周期,那么,我们可以在这些生命周期所对应的钩子函数来做一些额外的事儿。
那么,一次完整的导航解析包含的流程如下:
一次完整的导航解析流程如下:
- 导航被触发。
- 在失活的组件里调用离开守卫。
- 调用全局的 beforeEach 守卫。
- 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
- 在路由配置里调用 beforeEnter。
- 解析异步路由组件。
- 在被激活的组件里调用 beforeRouteEnter。
- 调用全局的 beforeResolve 守卫(2.5+)。
- 导航被确认。
- 调用全局的 afterEach 钩子。
- 触发 DOM 更新。
- 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
下面是一个全局导航守卫的快速入门示例:
router.beforeEach((to,from,next)=>{
console.log('现在进入了 beforeEach');
console.log('to:',to);
console.log('from:',from);
next(); // 必须要调用 next 方法,才会进入下一个组件
})
next 方法可以接收参数,具体的参数信息如下:
next 方法的参数有以下几种可能:
-
next( ):进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed(确认的)。
-
next(false):中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
-
next(’/’) 或者 next({ path: ‘/’ }):跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
-
next(error):(2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError 方法中注册过的回调。
本文地址:https://blog.csdn.net/twoyearTrainee/article/details/107456943