路由发展阶段
后端路由阶段
前后端分离路由阶段
单页面富应用阶段
✍URL的hash
✍HTML5的History
✍Vue Router 路由
- 在前端里,路由可以理解为用来描述页面地址 URL 和组件之间的映射关系
- 单页面应用,简称 SPA,Single Page Application,指的是只有一个 HTML 页面的应用程序。
- vue-router是基于路由和组件的
- 路由用于设定访问路径, 将路径和组件映射起来
- 在vue-router的单页面应用中, 页面的路径的改变就是组件的切换
安装vue-router路由
npm install vue-router --save
如果需要在一个已经创建好的 Vue 项目中添加 Vue Router,可以通过以下命令:
vue add router
使用 vue-router 的步骤(vueCLI)
1.创建路由需要映射的组件(打算显示的页面)
- 脚手架vueCLI自动创建组件 --------------- HomeView.vue
2.创建路由模块
- 使用 vueCLI(包含router插件) 初始化项目,在 源代码目录下,
/src/router/index.js
路由模块,并初始化如下的代码
// 1.导入 Vue 和 VueRouter 的包
import Vue from 'vue'
import VueRouter from 'vue-router'
//3.引入需要映射的组件
import HomeView from '../views/HomeView.vue'
// 2.调用 Vue.use() 函数,把 VueRouter 安装为 Vue 的插件
Vue.use(VueRouter)
// 4.创建 VueRouter 对象
const routes = [ // 在 routes 数组中,声明路由的匹配规则
{
path: '/', // path 表示要匹配的 url 地址
name: 'Home', //表示要展示的路由组件的name名字
component: Home //component 表示要展示的路由组件
},
{
path: '/about',
name: 'About',
// 这种方式是路由懒加载, (webpackChunkName,webpack打包时的备注)
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
//配置路由模式 'history' 或 'hash'
mode: 'history',
// 配置路由和组件之间的映射关系
routes
})
// 5.将 router 对象抛出,让其传入到 vue 实例中
export default router
2.1声明路由匹配规则
- path是访问组件的url地址。将在浏览器的地址栏中体现
- name是给vue路由内部使用的。可以不填写,一般情况我们写成和path一致即可。不可以重复
- component路由地址所对应的组件,输入地址后就显示该组件
const routes = [ // 在 routes 数组中,声明路由的匹配规则,每个对象都是 路由节点
{
path: '/', // path 表示要匹配的 url 地址
name: 'Home', //表示要展示的路由组件的name名字
component: Home //component 表示要展示的路由组件
},
]
2.2 路由重定向 redirec
const routes = [ // 在 routes 数组中,声明路由的匹配规则,每个对象都是 路由节点
{
path: "/", //默认路由首页 "/"根路径
redirect: "/home" //路由重定向redirect 将根路径重定向到/home的路径下
}
]
2.3 懒加载 component
-
路由懒加载必须使用箭头函数的形式来配置component属性
-
import是懒加载组件时使用的方法,该方法的参数是页面组件的完整路径
-
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载
-
SPA首屏优化,只有在解析路由时才会加载组件,减小入口文件积
const routes = [ // 在 routes 数组中,声明路由的匹配规则,每个对象都是 路由节点
{
path: '/about',
component: () => import( '../views/About.vue')
}
]
2.4 路由别名 alias
- 在路由配置时,可以通过
alias
来配置路由别名,即 path 的备用地址。 - 支持字符串,支持数组
const routes = [ // 在 routes 数组中,声明路由的匹配规则,每个对象都是 路由节点
{
path: "/", //首页
alias: ["/home", "/index"], //路由别名 支持字符串,支持数组
name: "home",
component: HomeView
},
]
2.5 自定义的数据 meta 路由元信息
const routes = [ // 在 routes 数组中,声明路由的匹配规则,每个对象都是 路由节点
{
path: "reg",
name:"reg",
component:()=>import("../views/home/RegView.vue"),
meta:{
title:"会员注册"
}
},
]
- 通过路由渲染组件时,有一些组件需要缓存(keep-alive),有一些组件不需要缓存时,就可以通过 meta 来对路由状态进行标记
const routes = [ // 在 routes 数组中,声明路由的匹配规则,每个对象都是 路由节点
{
path: "reg",
name:"reg",
component:()=>import("../views/home/RegView.vue"),
meta:{
isKeepAlive:true, //该路由节点被缓存
}
},
]
<keep-alive>
<router-view v-if="$route.meta.isKeepAlive">前台二级路由</router-view>
</keep-alive>
2.6 通用路由 *
- 可以给路由的 path 属性设置为
*
,表示通用路由,可以匹配任意路由。通常将该路由配置放在所有路由最后,用来进行错误路径的处理:
const routes = [ // 在 routes 数组中,声明路由的匹配规则,每个对象都是 路由节点
{
path:"/err",
component: () => import("../views/ErrorView.vue")
},
{
path: "*", //通用路由 写在路由表中的最后面
//component: () => import("../views/ErrorView.vue") //404
redirect:"/err"//重定向
}]
2.7 动态路由
- 把 Hash 地址中可变的部分 定义为参数项 ,需要通过
/:变量名
来与路径匹配 - 从而提高路由规则的复用性
const routes = [ // 在 routes 数组中,声明路由的匹配规则,每个对象都是 路由节点
{
path: "/detail/:id", //电影详情 带参数, ?该参数可以不带
name: "detail",
component: () => import("../views/DetailView.vue")
},
]
- 可选动态路由
/:变量名?
- 下例表示
detail
路径末尾有没有动态部分都可以匹配到该路由
const routes = [ // 在 routes 数组中,声明路由的匹配规则,每个对象都是 路由节点
{
path: "/detail/:id?", //电影详情 带参数, ?该参数可以不带
name: "detail",
component: () => import("../views/DetailView.vue")
},
]
<router-link :to="'/detail/'+item._id"> 带参数的跳转 </router-link>
3.挂载路由模块
- 在源代码目录下 src/ main.js 入口文件中,导入路由模块并在 Vue实例中 挂载 路由模块
import Vue from 'vue'
import App from './App.vue'
// 1.导入第一步暴露的路由模块
import router from './router'
//关闭生产模式下给出的提示
Vue.config.productionTip = false
new Vue({
// 2.在 Vue实例中 挂载 路由模块
router,
render: h => h(App)
}).$mount('#app')
将render: h => h(App) 根据es6语法分解为:
render: h => h(App);
等价于
render: h => {return h(App);}
等价于
render: function(h) { return h(App);}
等价于
render: function(createElement) { return createElement(App); }
render函数用来渲染视图,也提供给el挂载,所以使用render函数就是为了页面显示出来。
1.render 方法是一个函数,在接受传入的参数 h 函数后,返回 h(App) 的函数调用结果。
2.在创建 vue 实例时,通过调用 render 方法来渲染实例页面的 DOM 结构。
3.当vue 在调用 render 方法时,会传入一个 createElement 函数作为参数,h 的实参是 createElement 函数,然后 createElement 会以 App为参数进行调用。
4.路由跳转<router-link>
和 路由出口<router-view>
<router-link
> 属性
to
(必选)
- 指定跳转路径
- 值是一个字符串,或者是一个对象
- 默认渲染成带有正确链接的
<a>
标签
//绑定字符串
<router-link to='/home'>详情页</router-link>
//动态绑定字符串
<router-link v-bind:to="'/movie'">Movie</router-link>
//动态绑定对象
<router-link v-bind:to="{ path: '/home' }">Movie</router-link>
tag
- 类型: string ;默认值: “a”
- 指定
<router-link>
之后渲染成什么组件,比如下面的代码会被渲染成一个<li>
元素,而不是<a>
<router-link to='/home' tag='li'>详情页</router-link>
replace
- 类型: boolean ; 默认值: false
- 不会留下 history 记录,后退键返回不能返回到上一个页面中
- 会调用
router.replace()
,而不是router.push()
;
<router-link :to="{ path: '/abc'}" replace></router-link>
active-class
-
设置激活a元素后应用的class名,默认是router-link-active
-
设置 active-class 可以修改默认的名称(一般不需要改)
- 在进行高亮显示的导航菜单或者底部tabbar时, 会使用到该类
- 但是通常不会修改类的属性, 会直接使用默认的router-link-active即可
-
<router-link :to="{path:'/about'}" active-class="activeClass">about</router-link>
exact-active-class (路由嵌套)
- 链接精准激活时,应用于渲染的
<a>
的 class,默认是router-link-exact-active
代码路由传参
跳转传参
$router.push
this.$router.push(url)
this.$router.push({path:url}) //this.$router.push({path:"/home"})
this.$router.push({name:"movies"}) //this.$router.push({name:"adminindex"})
1、通过地址栏传参query(相当于get请求)
this.$router.push({
path: 路由的路径(path),
query: {
id: new Date().getTime(),
url: menuIndex
}
});
缺点:
- 地址栏是使用?传参。因此地址的传送的数据长度有限制,不可以超过255个字符
- 地址栏传参时数据会明文的显示在地址栏上面,因此一些敏感数不适合通过地址栏传参
1.1 query传 对象时 注意
- 如果是query,进行传参,传入的是对象的时候, 页面进入时能正确获取到此对象, 但当刷新页面时,此参数值成了’[object object]', 原因: String({})为"[object Object]" , 没错将对象转成了字符串,可以用JSON格式来解决
//传参
this.$router.push({
path: "/path",
query: { data:JSON.stringify(data)}
});
//取值
let data=JSON.parse(this.$route.query.data);
2、路由的params传参(相当于后端的post请求,会把请求体封装起来)
this.$router.push({
name: 路由的name属性,
params: {
id: "aaa",
pwd: "654321woniu"
}
});
- params传参,数据不会明文显示在地址栏
缺点:
- 刷新页面时,当前传递的参数会消失
$router.replace
-
push 和 replace 的区别:
- push 会增加一条历史记录
- replace 不会增加历史记录,而是替换掉当前的历史记录
$router.go
- 可以在浏览历史中前进和后退
<template>
<div>
<h3>Home组件</h3>
<button @click="goBack"> 后退 </button>
</div>
</template>
<script>
export default {
name: "Home",
methods: {
goBack(){
// 后退到之前的组件页面
this.$router.go(-1)
}
}
}
</script>
<style scoped>
</style>
- vue-router 提供了如下两个便捷方法
- $router.back()
在历史记录中, 后退到上一个页面 - $router.forward()
在历史记录中, 前进到下一个页面
- $router.back()
获取动态路由的值
- vue3中,在setup中,使用vue-router库 提供的一个 hook useRoute
- 为了简化路由参数的获取形式,vue-router 允许在 路由规则中开启 props 传参
const routes = [ // 在 routes 数组中,声明路由的匹配规则,每个对象都是 路由节点
{
path: '/user/:id',
component: User,
props: true // 打开这个选项,跳转后的页面就可以通过props接收 路由参数
},
]