路由基础
路由含义
服务器端的路由: 一个地址指向一个资源页面
前端的路由:框架式开发都是单页面(SPA)应用
- single page application 单页面应用
- 优点:体验感好,组件化开发
- 缺点:不利于seo,首页加载慢
- multiple page appliction 多页面应用
- 优点:seo友好
- 缺点:复用不好
- single page application 单页面应用
简单实现路由:
hash
hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页,也就是说hash 出现在 URL 中,但不会被包含在 http 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;
Hash模式:通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据。
监听
hashchange变化,修改动态组件的内容1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41<template>
<div id="app">
<component :newURL="cur"></component>
</div>
</template>
<script>
import index from "@/pages/index"
import car from "@/pages/car"
import user from "@/pages/user"
export default {
name: 'App',
data() {
return {
cur:"index"
}
},
components: {
index,user,car
},
mounted() {
let _this = this;
window.addEventListener("hashchange",function(e){
console.log(e)
let url = e.newURL.split("#")[1].slice(1)
if(url){
_this.cur = url;
}else{
_this.cur = 'index'
}
})
},
}
</script>
<style>
*{
margin: 0;
padding: 0;
}
</style>
vue-router
WebApp的链接路径管理系统, 是vue生态圈里非常重要的内容
使用:
安装vue-router
1
npm i vue-router --save
在src下面创建router文件夹,下面创建index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import Vue from "vue";
import VueRouter from "vue-router";
// Vue.use(插件名) 安装插件
Vue.use(VueRouter);
// 引入页面组件
import 组件A from "@/pages/组件A"
import 组件B from "@/pages/组件B"
import 组件C from "@/pages/组件C"
// 实例化一个路由对象
let router = new VueRouter({
routes:[
{ path:"/a",component:组件A },
{ path:"/b",component:组件B },
{ path:"/c",component:组件C },
]
})在App.vue 模板里面写入
router-view标签,路由地址切换之后对应的组件内容展示在这里使用
router-link实现a标签。 to的值就是 路由映射配置里面的path内容
在脚手架初始项目的时候就选择安装vue-router,自动设计好所有配置
404配置
默认情况下,访问一个没有被定义的路由地址, 页面是不会渲染任何内容。我们可以给他指定到404页面
实现
1
2
3
4
5
6
7{
routes:[
{ path:"*",component:404组件 }
]
}
激活class
需要设置激活的class, 当前的路由地址和a标签一致的时候,a标签就应该激活
实现:
1
2
3
4
5
6
7{
linkActiveClass:'自定义class名', // 非严格模式 但是可以在某个router-link上面加上exact属性,变成严格模式
linkExactActiveClass:'自定义class名' // 严格模式
routes:[
{ path:"*",component:404组件 }
]
}
重定向
1 | { |
命名路由
1 | routes:[ |
1 | <router-link to="/地址A"></router-link> |
1 | <router-link :to="{name:'名称A'}"></router-link> |
动态路由
使用场景:
- 新闻列表 到新闻详情 详情需要知道新闻id。
- 新闻分类 到新闻列表 新闻列表需要知道新闻分类id
- 愿望: 实现页面之间的传递参数吗
使用:
1
2
3
4
5{
routes:[
{ path:"/地址A/:标识符",component:组件A },
]
}1
<router-link to="/地址A/数据"></router-link>
1
2// 组件A里面
this.$route.params.标识符实现了两个页面之间的传参
注意:
当我们在main.js中将路由挂载到vue实例上面去之后, 所有的组件对象里面都会多两个属性,一个
$router,$route$router表示这个路由实例对象$route表示当前页面的路由信息- this.$route.params 动态路由数据
- this.$route.name 路由名称
- this.$route.meta 元数据
- this.$route.query search参数
- this.$route.matched 路径信息
如何实现页面之间传参
动态路由
query传参
1
<router-link to="/地址B?key=val"></router-link>
1
this.$route.query.key
本地存储
- localStorage.setItem(“key”,val)
- localStorage.getItem(“key”)
路由升级
编程式导航
原生JS实现页面跳转方式:
- a href
- JS 编程式导航
- location.href assign replace
- history.back forward go
$router
push
replace
go
back
forward
嵌套路由
1 | { |
1 | // 组件A里面一定要有一个router-view |
命名视图
视图就是
router-view默认情况下: 一个路由只能渲染一个组件到一个指定的位置
如果我们希望访问一个路由的时候,同时渲染多个组件到不同位置,这个时候就可以使用命名视图
实现:
1
2
3
4
5
6
7
8
9
10
11
12
13{
routes:[
{
path:"/地址A", //一级路由
components:{
default:组件A,
x:组件X,
y:组件y
},
}
]
}1
2
3<router-view name='default'></router-view> 默认视图,可以不要name属性
<router-view name='x'></router-view> 组件x渲染在这
<router-view name='y'></router-view> 组件y渲染在这
元信息
1 | routes:[ |
1 | this.$route.meta.key // 可以获取数据 |
导航守卫
什么是导航守卫
进入路由、离开路由、更新路由的时候自动执行的函数。 又称之路由钩子函数
分类
- 全局守卫
- 前置守卫 路由进入之前会执行的函数 beforeEach
- 设置标题
- 权限判断
- 后置守卫 路由离开后执行的函数 afterEach
- 前置守卫 路由进入之前会执行的函数 beforeEach
- 局部守卫
- 前置守卫
- 更新守卫
- 后置守卫
路由懒加载
原来的路由配置文件里面都是通过import 导入所有的组件。这样做,应用开始的时候就会导入这些所有的组件,增加了负担
1
2
3
4
5
6
7
8
9
10
11
12import Index from "@/pages/Index"
import About from "@/pages/About"
import New from "@/pages/New"
import NewInfo from "@/pages/NewInfo"
import User from "@/pages/User"
import UserOrder from "@/pages/UserOrder"
import UserClass from "@/pages/UserClass"
import UserSet from "@/pages/UserSet"
import UserIndex from "@/pages/UserIndex"
import NotFound from "@/pages/NotFound"
import Adv from "@/components/Adv"
import Login from "@/pages/Login"希望打开哪个路由地址的时候就再去加载对应的路由组件。 这就是路由懒加载
1
2
3
4
5import 组件名 from "@/pages/组件名"
{
path:"/地址",
component:组件名
}1
2
3
4
5{
path:"/地址",
component:()=>import("@/pages/组件名")
}