路由
- 理解:一个路由(route)就是一组映射关系(key-value),多个路由需要路由器(router)进行管理
- 前端路由:key是路径,value是组件
基本使用
- 安装vue-router:
npm i vue-router
- 使用插件:
Vue.use(VueRouter)
- 设置router配置项:
// 引入VueRouter
import VueRouter from 'vue-router'
// 引入路由组件
import a from '../components/A';
import b from '../components/B';
// 创建router实列对象
const router = new VueRouter({
routes: [
{
path: '/A', // 设置路径名
component: a // 设置显示的组件
},
{
path: 'B',
component: b
}
]
})
- 实现切换(active-class可配置高亮样式)
<router-link active-class="active">a</router-link>
- 指定展示位置
<router-view></router-view>
注意事项
- 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹
- 通过切换被隐藏了的路由组件,默认是被销毁的
- 每个组件都有自己的$route属性,里面存储着自己的路由信息
- 整个应用只有一个router,可以通过组件的$router属性获取到
多级路由(嵌套路由)
- 配置路由规则,使用children配置项
routes: [
{
path: '/father',
component: Father,
children: [
{
// 注意:子路由不需要写'/'
path: 'child',
component: Child
}
]
}
]
- 跳转(要写完整路径)
<router-link to="/father/child">i am child</router-link>
路由的query参数
- 传递参数
// 转路由并携带query参数,to的字符串写法
<router-link :to="`/home/message/detail?id=${value.id}&title=${value.title}`">{{ value.title }}</router-link>
// 跳转路由并携带query参数,to的对象写法
<router-link :to="{
path:'/home/message/detail',
query:{
id: value.id,
title: value.title
}
}">
{{value.title}}
</router-link>
- 接收参数
$route.query.id
$route.query.title
命名路由
- 作用:简化路由的跳转(当路径过长时使用)
- 使用:
// 命名
routes: [
{
path: '/father',
component: Father,
children: [
{
name: 'test'
path: 'child',
component: Child
}
]
}
]
// 简化跳转
// 简化前
<router-link to="/father/child"></router-link>
// 简化后
<router-link :to="{name:'test'}"></router-link>
// 配合传递参数
<router-link :to="{
name: 'test',
query: {
id: 001,
title: 'one'
}
}">跳转</router-link>
路由的params参数
- 配置路由,声明接收params参数
routes: [
{
path: '/father',
component: Father,
children: [
{
name: 'test'
path: 'child/:id/:title', //使用占位符声明接收params参数
component: Child
}
]
}
]
- 传递参数
<!-- 跳转路由并携带params参数,to的字符串写法 -->
<router-link :to="`/home/message/detail/${value.id}/${value.title}`">{{ value.title }}</router-link>
<!-- 跳转路由并携带params参数,to的对象写法 -->
<router-link :to="{
// 使用params时,不可以使用path,只能用name
name:'xiaoxi',
params:{
id: value.id,
title: value.title
}
}">
{{value.title}}
</router-link>
注意:使用params时,若使用to的对象写法,不可以使用path,只能用name
路由的props配置
作用:让路由组件更方便地收到参数
routes: [
{
path: '/father',
component: Father,
children: [
{
name: 'test'
path: 'child/:id/:title', //使用占位符声明接收params参数
component: Child,
//props写法一,值为对象
// props: {a:1, b:'hello'}
//props写法二,值为布尔值,若为真,则将该组件收到的所有params参数以props的形式传给组件
// props: true
//props写法三,值为函数
props($route) {
return {
id: $route.params.id,
title: $route.params.title
}
}
}
]
}
]
的replace属性
- 作用:控制路由跳转时操作浏览器历史记录的模式
- 浏览器的历史记录有两种写入方式,分别为push和replace,默认为push
- 使用:
//简写
<router-link replace>...</router-link>
//完整
<router-link :replace="true">...</router-link>
编程式路由导航
- 作用:不借助
<router-link>
实现路由跳转,让路由跳转更加灵活 - 使用
this.$router.push({
name: 'xxx',
params: {
id: xxx,
title: xxx
}
})
this.$router.replace({
name: 'xxx',
params: {
id: xxx,
title: xxx
}
})
//回退
this.$router.back()
//前进
this.$router.forward()
//自定义
this.$router.go(1)//1表示前进一个,-3表示后退3个
缓存路由组件
- 作用:让不展示的路由组件保持挂载,不被销毁
- 使用:
//include选择包含的组件名,若不写include,则该组件下的子组件都缓存
<keep-alive include="xxx">
<router-link></router-link>
</keep-alive>
//若想选择缓存多个
<keep-alive :include="['aaa', 'bbb']">
<router-link></router-link>
</keep-alive>
两个新的生命周期钩子
- 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态
- 使用:
export default {
name: 'News',
data() {
return {
opacity: 1
}
},
//路由组件被激活时触发
activated() {
this.timer = setInterval(() => {
this.opacity -= 0.01
if (this.opacity <= 0) {
this.opacity = 1;
}
}, 16)
},
//路由组件被失活时触发
deactivated() {
clearTimeout(this.timer)
}
}
路由守卫
- 作用:对路由进行权限控制
- 分类:全局守卫、独享守卫、组件内守卫
全局守卫
- 前置
beforeEach((to, from, next)=>{...})
//全局前置路由守卫-初始化时被调用。每次路由切换之前被调用
router.beforeEach((to, from, next) => {
console.log(to, from);
if (to.meta.isAuth) { //判断是否有权限
if (localStorage.getItem('school') === 'a') {
next();
} else {
alert('无权限')
}
} else {
next();
}
});
- 后置
afterEach((to, from)=>{...})
//全局后置路由守卫-初始化时被调用。每次路由切换之后被调用
router.afterEach((to, from) => {
if(to.meta.title){
document.title = to.meta.title || '默认'; //修改网页title
}else{
document.title = 'xxx';
}
})
独享路由守卫
beforeEnter((to, from)=>{...})
beforeEnter:(to,from,next)=>{
console.log('独享路由守卫', to, from);
if(to.meta.isAuth){
if(localStorage.getItem('a')==='a'){
next();
}else{
alert('无权限');
}
}else{
next();
}
}
组件内守卫
//进入守卫:通过路由规则进入该组件时被调用
beforeRouteEnter(to, from, next){
...
},
//离开守卫:通过路由规则离开该组件时被调用
beforeRouteLeave(to, from, next){
...
}
路由器的两种工作模式
- 对于url来说,#及其后面的内容是hash值
- hash值不会包含在http请求中,即:hash值不会带给服务器
hash模式
- 地址中带着#,不美观;
- 若将地址通过第三方手机app分享,若app校验严格,地址会被标记为不合法;
- 兼容性较好
history模式
- 地址干净、美观;应用部署需要后端设置,解决刷新页面404的问题
- 可以使用
connect-history-api-fallback
这个npm,配置app.use(history())
,即可解决(要配置在静态资源引入之前)
Vue UI组件库
移动端常用
PC端常用
使用
完整引入
//引入elementUI组件库
import ElementUI from 'element-ui';
//引入elementUI全部样式
import 'element-ui/lib/theme-chalk/index.css';
//应用elementUI
Vue.use(ElementUI);
按需引入
import { Button, DatePicker } from 'element-ui';
Vue.component(Button.name, Button); //Button.name即使用elementUI中Button组件的命名,也可以自己修改为要使用的名字
Vue.component(DatePicker.name, DatePicker);
在babel.config.js
中配置
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
["@babel/preset-env", { "modules": false }]
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}