Vue-Router笔记大全
一、路由的本质和分类
1、路由的本质
路由是指根据不同的 URL 地址,来展示不同的内容或功能。在前端开发中,路由是指在单页面应用(SPA)中,根据用户在浏览器中输入的 URL,将对应的组件或页面渲染到页面上的机制。
路由的本质是将 URL 地址映射到具体的组件或页面上。在单页面应用中,不同的 URL 地址对应着不同的组件或页面,这些组件或页面都是通过前端路由实现的。前端路由通过监听 URL 地址的变化,根据变化来选择对应的组件或页面进行渲染,从而实现页面无刷新的更新和切换。
2、分类
路由可以分为前端路由和后端路由
二、后端路由
1、概念和本质
现在我来说说后端路由,后端路由就是根据不同用户URL请求返回不同的内容,其本质是URL请求地址和服务器资源之间的对应关系
2、SPA(Single Page Application)
- 后端渲染(存在性能问题)
- Ajax前端渲染(前端渲染提高性能,但是不支持浏览器的前进后退操作)
- SPA单页面应用程序:整个网站只有一个页面,内容的变化通过Ajax局部更新实现,同时支持浏览器地址栏的前进和后退操作
- 实现原理:基于URL地址的hash(hash的变化会导致浏览器记录访问历史的变化,但是hash的变化不会触发新的URL请求)
- 在实现SPA过程中,最核心的技术点就是前端路由
三、前端路由
1、概念和本质
概念:根据不同的用户事件显示不同的页面内容
本质:用户事件与事件处理函数之间的对应关系
四、实现简易的前端路由(未使用vue router)
1、监听window.onhashchange事件,根据获取得到最近的hash值,切换要显示的组件的名称
2、通过location.hash获取最新的hash值
3、做switch 与 case判断,从而决定显示什么内容
//监听window.onhashchange事件。
//根据获取得到最近的hash值,切换要显示的组件的名称
window.onhashchange = function(){
//通过location.hash获取最新的hash值
//做switch 与 case判断,从而决定显示什么内容
}
1.模拟路由.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<!-- 导入 vue 文件 -->
<script src="./lib/vue_2.5.22.js"></script>
</head>
<body>
<!-- 被 vue 实例控制的 div 区域 -->
<div id="app">
<!-- 切换组件的超链接 -->
<a href="#/zhuye">主页</a>
<a href="#/keji">科技</a>
<a href="#/caijing">财经</a>
<a href="#/yule">娱乐</a>
<!-- 根据 :is 属性指定的组件名称,把对应的组件渲染到 component 标签所在的位置 -->
<!-- 可以把 component 标签当做是【组件的占位符】 -->
<component :is="comName"></component>
</div>
<script>
// #region 定义需要被切换的 4 个组件
// 主页组件
const zhuye = {
template: '<h1>主页信息</h1>'
}
// 科技组件
const keji = {
template: '<h1>科技信息</h1>'
}
// 财经组件
const caijing = {
template: '<h1>财经信息</h1>'
}
// 娱乐组件
const yule = {
template: '<h1>娱乐信息</h1>'
}
// #endregion
// #region vue 实例对象
const vm = new Vue({
el: '#app',
data: {
comName: 'zhuye'
},
// 注册私有组件
components: {
zhuye,
keji,
caijing,
yule
}
})
// #endregion
// 监听 window 的 onhashchange 事件,根据获取到的最新的 hash 值,切换要显示的组件的名称
window.onhashchange = function() {
// 通过 location.hash 获取到最新的 hash 值
console.log(location.hash);
switch(location.hash.slice(1)){
case '/zhuye':
vm.comName = 'zhuye'
break
case '/keji':
vm.comName = 'keji'
break
case '/caijing':
vm.comName = 'caijing'
break
case '/yule':
vm.comName = 'yule'
break
}
}
</script>
</body>
</html>
五.Vue Router简介
刚刚我们使用js与vue实现了一个简易的路由,但是实际工作中我们并不推荐这么做,而是推荐使用Vue.js官方提供的路由管理器,它是一个功能更加强大的前端路由器,更符合企业级项目的需要。
Vue Router(官网:https://router.vuejs.org/zh/)和Vue.js的核心深度集成,可以一起方便的实现SPA(single page web application,单页应用程序)应用程序的开发。
Vue Router依赖于Vue,所以需要先引入Vue,再引入Vue Router
Vue Router的特性:
支持H5 History模式或者hash模式
H5路由有两种模式:History模式和hash模式。
hash模式:在URL中添加#号,用于表示当前页面的状态,每当#后面的内容发生变化时,不会向服务器发送请求,而是触发hashchange事件,可以通过监听这个事件来做出相应的处理。
History模式:通过HTML5的history API来操作浏览器的历史记录,改变URL的路径部分,同时不刷新页面。在这种模式下,服务器需要对所有的URL进行配置,确保当用户访问某个URL时,返回的是正确的HTML文件,而不是404错误页面。
两种模式的选择需要根据具体情况而定。如果需要支持低版本浏览器,那么使用hash模式比较保险;如果需要在URL中使用更加语义化的路径,那么可以选择历史模式。
支持嵌套路由
嵌套路由是指在 Vue Router 中,可以将多个组件嵌套在同一个路由下,并将它们组合在一起形成一个完整的页面。在这个页面中,每个组件可以负责不同的内容区域,而这些组件又可以进一步嵌套其他子组件。
支持路由参数
路由参数是指通过路由传递的动态参数,可以在路由路径中使用冒号标识,如/users/:id
,其中:id
就是一个路由参数,它可以匹配任意字符,包括数字、字母、中文等。在路由匹配时,路径中的参数会被提取出来,作为路由组件的props属性传递给组件。这样就可以实现动态生成路由组件的效果,方便我们根据不同参数显示不同的内容。
支持编程式路由
编程式导航是通过代码控制页面的路由导航,可以实现在用户操作之外的跳转页面、跳转到动态路由等功能。在Vue Router中,常用的编程式导航方法包括以下几种:
-
this.$router.push(location)
:跳转到新路由,新路由可以是一个路径字符串或者一个描述地址的对象,例如:// 跳转到 /foo this.$router.push('/foo') // 跳转到 /bar,并且带有 query 参数 this.$router.push({ path: '/bar', query: { q: 'keyword' }})
-
this.$router.replace(location)
:与push
方法类似,不同之处在于replace
方法不会留下浏览历史记录,使用该方法可以在返回时不返回到上一个路由。 -
this.$router.go(n)
:跳转到当前路由的前一个或者后一个路由,n
表示前进或者后退的步数,例如this.$router.go(-1)
表示返回上一个路由。 -
this.$router.back()
:等同于this.$router.go(-1)
,返回上一个路由。 -
this.$router.forward()
:等同于this.$router.go(1)
,前进到下一个路由。
这些方法可以在Vue组件中通过this.$router
访问到,常用于事件触发、异步操作中的回调函数中等场景,用来控制页面路由跳转、路由参数等。需要注意的是,在使用编程式导航时,应该避免直接操作URL,而是通过路由的名称、路径或者参数进行导航。
支持命名路由
命名路由是为了在应用程序中定义路由时,可以为每个路由起一个独特的名称,以便在代码中方便地引用这些路由。通过给路由起一个独特的名称,我们可以使用 $router.push({ name: 'route-name' })
和 $router.replace({ name: 'route-name' })
等方法来导航到指定的路由。
下面是一个示例,演示了如何定义和使用命名路由:
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
},
{
path: '/post/:postId',
name: 'post',
component: Post
}
]
})
// 通过命名路由导航到 user 路由
router.push({ name: 'user', params: { userId: '123' }})
在这个示例中,我们定义了两个路由,user
和 post
,并且给每个路由起了一个独特的名称。通过 $router.push({ name: 'user', params: { userId: '123' }})
,我们可以使用命名路由导航到 user
路由,并且传递了一个 userId
参数。
命名路由经常和编程式导航一起使用吗?
是的,命名路由通常会和编程式导航一起使用,因为在某些场景下需要通过代码触发路由跳转。命名路由提供了一种简单方便的方式来管理路由跳转,而编程式导航则可以在代码中通过指定路由名称来触发跳转。同时,命名路由还可以提高代码的可读性和可维护性。
支持路由导航守卫
路由导航守卫是 Vue Router 提供的一种机制,它可以让开发者在切换路由时拦截导航,并进行相应的处理。
Vue Router 提供了三种导航守卫:
-
beforeEach
: 在路由切换开始时调用,可以用来进行用户权限校验等操作。 -
beforeResolve
: 在路由组件被解析时调用,可以用来进行路由组件的懒加载等操作。 -
afterEach
: 在路由切换成功后调用,可以用来进行页面跳转后的操作,如页面统计等。
使用路由导航守卫可以实现很多高级的路由功能,如路由权限控制、动态路由匹配、路由重定向等。同时也可以进行页面的统计和监控,更好地了解用户行为,优化用户体验。
支持路由过渡动画特效
支持路由懒加载
路由懒加载是指将路由的组件按需加载,而不是在应用程序加载时一次性加载所有的组件。这样可以提高应用程序的性能,减少初始加载时间,并减少资源消耗。在使用路由懒加载时,只有在路由被访问时才会加载相应的组件,而不是在应用程序启动时加载所有组件。
使用路由懒加载需要使用Webpack的代码分割功能,通过代码分割,Webpack会将每个组件打包成单独的文件,只有在需要时才会加载这些文件。在Vue.js中,可以通过动态import语法来实现路由懒加载,例如:
const Foo = () => import('./Foo.vue')
const Bar = () => import('./Bar.vue')
const router = new VueRouter({
routes: [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
})
在这个例子中,Foo
和Bar
是两个组件,它们使用了动态import语法来实现路由懒加载。当访问/foo
路径时,Foo
组件会被加载;当访问/bar
路径时,Bar
组件会被加载。
支持路由滚动行为
路由滚动行为是指在切换路由时,页面应该如何滚动。默认情况下,页面切换后会保持之前的滚动位置不变,但有时需要在切换路由时自动滚动到页面顶部或其他指定位置。
在 Vue Router 中,可以通过设置路由元信息的 scrollBehavior
属性来定义路由的滚动行为。具体来说,需要在路由配置文件中定义 scrollBehavior
函数,该函数接收三个参数:
to
: 即将进入的目标路由对象from
: 当前导航正要离开的路由savedPosition
: 通过浏览器的前进或后退按钮触发导航时,会有一个值为 true 的popstate
事件,此时会提供一个记录了滚动位置信息的savedPosition
属性。如果浏览器不支持popstate
事件,则为 null。
scrollBehavior
函数需要返回一个滚动位置对象,该对象有两个属性:x
和 y
,表示滚动位置的横向和纵向坐标。可以使用 JavaScript 的对象字面量语法来返回这个对象,例如:
scrollBehavior(to, from, savedPosition) {
return { x: 0, y: 0 }
}
上面的代码表示在切换路由时,自动滚动到页面顶部。
除了返回一个固定的滚动位置,scrollBehavior
函数还可以根据 to
和 from
参数来动态计算滚动位置。例如,在切换到某个具体路由时,需要滚动到该路由对应的某个元素位置,可以根据元素位置计算出滚动位置并返回。例如:
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return { selector: to.hash }
} else {
return { x: 0, y: 0 }
}
}
上面的代码表示如果目标路由包含哈希值,则滚动到对应元素的位置;否则滚动到页面顶部。
六.Vue Router的使用步骤(★★★)
A.导入js文件
先引入vue,再引入vue-router,因为vue-router在内部依赖vue,顺序不能颠倒。
1、导入vue文件,为全局window对象挂载vue构造函数
2、导入vue-router文件,为全局window对象挂载VueRouter构造函数
//导入vue文件,为全局window对象挂载vue构造函数
<script src="lib/vue_2.5.22.js"></script>
//导入vue-router文件,为全局window对象挂载VueRouter构造函数
<script src="lib/vue-router_3.0.2.js"></script>
B.添加路由链接:
<router-link>
是路由中提供的标签,默认会被渲染为a标签,to属性默认被渲染为href属性,
to属性的值会被渲染为#开头的hash地址
1、router-link是vue中提供的标签,默认会被渲染为a标签
2、to属性默认会被渲染成为href属性
3、to属性的值默认会被渲染为#开头的hash地址
<router-link to="/user">User</router-link>
<router-link to="/login">Login</router-link>
C.添加路由填充位(路由占位符)
1、将来通过路由规则匹配到的组件,将会被渲染到router-view所在的位置
<router-view></router-view>
D.定义路由组件
1、有两个路由链接,相对应地就需要两个路由组件
var User = { template:"<div>This is User</div>" }
var Login = { template:"<div>This is Login</div>" }
E.配置路由规则并创建路由实例(重要:着重记忆)
1、这个new VueRouter是头部文件导入的vue-router的js文件的构造函数
2、routes是路由规则数组
3、每一个路由规则都是一个对象,对象中至少包含path和component两个属性
4、path表示 路由匹配的hash地址,不要乱写,上面to里面写的什么这里就写什么,要一致
5、component表示路由规则对应要展示的组件对象
var myRouter = new VueRouter({
//routes是路由规则数组
routes:[
//每一个路由规则都是一个对象,对象中至少包含path和component两个属性
//path表示 路由匹配的hash地址,component表示路由规则对应要展示的组件对象
{path:"/user",component:User},
{path:"/login",component:Login}
]
})
F.将路由挂载到Vue实例中
在ES6中如果属性名与属性值相等,就直接简写,如果router:router就简写成router
new Vue({
el:"#app",
//通过router属性挂载路由对象
router:myRouter
})
小结:
Vue Router的使用步骤还是比较清晰的,按照步骤一步一步就能完成路由操作
A.导入js文件
B.添加路由链接
C.添加路由占位符(最后路由展示的组件就会在占位符的位置显示)
D.定义路由组件
E.配置路由规则并创建路由实例
F.将路由挂载到Vue实例中
七、路由重定向
路由重定向指的是:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面。
通过路由规则的redirect属性,指定一个新的路由地址,可以很方便地设置路由的重定向。
一句话:使用redirect属性,在用户访问地址A的时候,强制用户跳转到地址C
1、在路由规则中新增了一条路由规则
其中path表示需要被重定向的原地址,而redirect表示将要被重定向到的新地址
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
//其中path表示需要被重定向的**原地址**,而redirect表示将要被重定向到的**新地址**
{ path: '/', redirect: '/user'},
{ path: '/user', component: User },
{ path: '/register', component: Register }
]
})
八、导航守卫
导航守卫是指在路由切换时执行的一些操作,例如身份验证、路由重定向等。在前端框架中,如Vue.js和React等,都提供了相应的导航守卫功能。
在Vue.js中,导航守卫主要包括全局导航守卫、路由独享的导航守卫和组件内的导航守卫。全局导航守卫通过router.beforeEach()函数来实现,路由独享的导航守卫通过路由配置中的beforeEnter()函数来实现,组件内的导航守卫包括beforeRouteEnter()、beforeRouteUpdate()和beforeRouteLeave()函数,用于在组件内部控制导航守卫逻辑。
在React中,导航守卫通过React Router来实现,主要包括<Route>
组件和<Switch>
组件。在<Route>
组件中,可以使用render或者component属性来实现导航守卫功能,例如在render或者component函数中进行身份验证或者路由重定向等操作。在<Switch>
组件中,可以通过<Route>
组件的path属性和exact属性来匹配相应的路由,并且可以通过重定向<Route>
组件来实现路由重定向功能。
导航守卫在前端开发中非常重要,可以实现诸如身份验证、权限控制、路由重定向等功能,提高应用程序的安全性和可用性。
九、嵌套路由的用法:
1、嵌套路由功能分析
- 点击父级路由链接显示模板内容
- 模板内容中又有子级路由链接
- 点击子级路由链接显示子级模板内容
2、嵌套路由的用法:
A.父级路由链接、父级路由填充位
<!-- 父级路由链接 -->
<router-link to="/user">User</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
B.在父级模板中添加 子级路由链接、子级填充位
const Register = {
template: `<div>
<h1>Register 组件</h1>
<hr/>
<!-- 子路由链接 -->
<router-link to="/register/tab1">tab1</router-link>
<router-link to="/register/tab2">tab2</router-link>
<!-- 子路由的占位符 -->
<router-view />
<div>`
}
C.父级路由通过Children属性配置子级路由
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/', redirect: '/user'},
{ path: '/user', component: User },
// children 数组表示子路由规则
{ path: '/register',
component: Register,
children: [
{ path: '/register/tab1', component: Tab1 },
{ path: '/register/tab2', component: Tab2 }
]
}
]
})
整体代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<!-- 导入 vue 文件 -->
<script src="./lib/vue_2.5.22.js"></script>
<script src="./lib/vue-router_3.0.2.js"></script>
</head>
<body>
<!-- 被 vm 实例所控制的区域 -->
<div id="app">
<router-link to="/user">User</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
template: '<h1>User 组件</h1>'
}
const Register = {
template: `<div>
<h1>Register 组件</h1>
<hr/>
<!-- 子路由链接 -->
<router-link to="/register/tab1">tab1</router-link>
<router-link to="/register/tab2">tab2</router-link>
<!-- 子路由的占位符 -->
<router-view />
<div>`
}
const Tab1 = {
template: '<h3>tab1 子组件</h3>'
}
const Tab2 = {
template: '<h3>tab2 子组件</h3>'
}
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/', redirect: '/user'},
{ path: '/user', component: User },
// children 数组表示子路由规则
{ path: '/register', component: Register, children: [
{ path: '/register/tab1', component: Tab1 },
{ path: '/register/tab2', component: Tab2 }
] }
]
})
// 创建 vm 实例对象
const vm = new Vue({
// 指定控制的区域
el: '#app',
data: {},
// 挂载路由实例对象
// router: router
router
})
</script>
</body>
</html>
十、动态路由匹配/:
动态路由就是在路由路径中使用“动态路径参数”
简单理解为在路径后面加上 /:xx
//router.js
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:ids', component: User }
]
})
//about.vue
<template>
<div class="about">
//其值可以通过路由对象`$route`中的`params`属性来获取。
<h1>{{this.$route.params}}</h1>
</div>
</template>
如上面的例子,参数为id,其值可以通过路由对象$route
中的params
属性来获取。
$route与对应路由形成高度耦合,不够灵活,可以使用props
将组件和路由解耦。
耦合?说大白话就是用$route
的方式访问params,每次都要在前面加$route
,程序员不想写这么多重复代码,希望直接用id
就能访问到id,或者是自定义别的名字。
这时就出现了params属性:
1、首先在路由规则的定义中有一个props属性,设置为true,就可以使用props传递参数:
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/', redirect: '/user'},
{ path: '/user/:id', component: User, props: true },
{ path: '/register', component: Register }
]
})
2、然后在组件中定义props
第一个用法:它是一个bool
类型的值,传递参数,直接用就行:
const User = {
props: ['id'],
template: '<h1>User 组件 -- 用户id为: {{id}}</h1>'
}
还有一种用法:props是一个对象
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/', redirect: '/user'},
{ path: '/user/:id', component: User, props: { uname: 'lisi', age: 20 } },
{ path: '/register', component: Register }
]
})
即使props数组里面有id,也访问不到id
const User = {
props: ['id', 'uname', 'age'],
template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
}
还有一种用法:props的值为函数类型
既想用id,又想用props对象里面的数据,就要使用函数类型
里面的参数route是动态匹配的id
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/', redirect: '/user' },
{
path: '/user/:id',
component: User,
//参数route是动态匹配的id
props: route => ({ uname: 'zs', age: 20, id: route.params.id })
},
{ path: '/register', component: Register }
]
})
十一、命名路由的配置规则
为了更加方便地表示路由的路径,可以给路由规则起一个别名,即为“命名路由”
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/', redirect: '/user' },
{
// 命名路由
name: 'user',
path: '/user/:id',
component: User
}
]
})
相对应的,路由链接里面,可以这样写:
注意:这里的:to
前面要写:
<router-link :to="{ name: 'user', params: {id: 3} }">User3</router-link>
在使用router-link实现跳转页面的时候,除了可以直接写一个path路径之外,咱们还可以指定一个name,意思是,点当前链接,希望跳转到这个name所指定的user路由规则中,还可以使用params为这次跳转传递参数。
1、Vue-router编程式导航的两种方式
1、声明式导航:通过点击链接实现导航的方式,叫做声明式导航。
例如:普通网页中<a></a>
链接或者vue中<router-link></router-link>
2、编程式导航:通过调用JavaSript形式的API实现导航的方式,叫做编程式导航。
例如:普通网页中的location.href
2、编程式导航的基本用法
常用的编程式导航API如下:
- this.$router.push(‘hash地址’)
- this.$router.go(n)
看下面这个例子:
1、template模板中有一个button按钮,为button按钮绑定一个点击事件,点击就触发goRegister函数
2、在goRegister里面,使用this.$router.push('/register')
完成页面的跳转。this.$router.push()
的参数是一个hash地址
const User = {
props: ['id', 'uname', 'age'],
template: `<div>
<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>
<button @click="goRegister">跳转到注册页面</button>
</div>`,
methods: {
goRegister() {
this.$router.push('/register')
}
},
}
router.push()方法的参数规则如下:
十二、Vue-Router的三种模式
vue-router 有 3 种路由模式:Hash 模式、History 模式 和 memory history(abstract模式)
其中,hash 和 history 是 SPA 单页应用程序的基础。
先说结论: spa应用路由有2种模式,hash 和 history,vue路由有3种模式,比 spa 多了一个 abstract。
默认使用的是 hash 模式,当设置为 history 时,如果不支持 history 方法,也会强制使用 hash 模式。
当不在浏览器环境,比如 node 中时,直接强制使用 abstract 模式。
hash模式
Hash 模式(默认模式):
Hash 模式使用 URL 的哈希值(#)来模拟实际的路径。例如:http://example.com/#/user/1。在这种模式下,只有哈希值会发生变化,而不会触发浏览器发送请求给服务器。这意味着改变 URL 时,页面不会重新加载。Hash 模式兼容性较好,可以在所有现代浏览器和旧版浏览器中使用。
它有这样一些特点:
1、在第一个#后面出现的任何字符,都会被浏览器解读为位置标识符。这意味着,这些字符都不会被发送到服务器端。
2、单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页。
3、每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用"后退"按钮,就可以回到上一个位置。
4、可通过window.location.hash属性读取 hash 值,并且 window.location.hash 这个属性可读可写。
5、使用 window.addEventListener(“hashchange”, fun) 可以监听 hash 的变化
History 模式
History 模式:
History 模式使用 HTML5 的 History API (pushState, replaceState, popState) 来管理浏览历史记录。它可以让你的应用拥有干净的 URL,例如:http://example.com/user/1。不过,这种模式需要服务器端的支持,因为在没有正确配置的服务器上,用户访问一个直接指向某个子路径的 URL 时可能会导致 404 错误。为了解决这个问题,服务器需要配置为对所有未找到的页面都返回单页应用的 index.html 文件。
它有这样一些特点:
1、History 模式 使用 HTML5 中新增的 API,利用浏览器的history.pushState 和 history.replaceState 方法,实现不刷新页面的路由变化。
2、History 模式 可以直接修改浏览器地址栏中的 URL,而且不会带上 #,这样看起来更像传统的 URL。
3、使用 History 模式 时,前端可以通过监听 window 对象的 popstate 事件,来监听路由的变化。但是,它需要浏览器的支持,而不是所有的浏览器都支持 HTML5 中的 history API。
Memory History模式(也叫abstract)
MemoryHistory是最新版的Vue3.0的router,名字叫内存路由
在vue2中叫abstract模式.
它有这样一些特点:
Abstract(Memory History)模式是 Vue-Router 的一种模式,它在内存中保存路由历史而不依赖于浏览器的 URL。这种模式具有以下特点:
- 环境独立性:Abstract 模式不依赖于浏览器环境,因此它非常适用于服务器端渲染 (SSR)、原生应用和其他非浏览器环境中的 Vue.js。
- 无需服务器配置:由于 Abstract 模式不依赖于 URL,因此无需进行特定的服务器配置。
- 内存中的路由历史:Abstract 模式将整个路由历史保存在内存中,而不是在浏览器的地址栏中。这意味着在使用 Abstract 模式的应用中,用户无法通过直接输入 URL 或使用浏览器的前进/后退按钮来导航。
- 更简单的测试:由于 Abstract 模式与浏览器环境无关,因此在进行单元测试或集成测试时,可以更容易地模拟导航和路由行为。
- 不常用于浏览器端:虽然 Abstract 模式在浏览器端也可以使用,但它并不常见,因为在这种情况下,用户无法使用浏览器的前进/后退按钮或直接访问特定 URL。
- 根据应用的场景和需求,可以选择使用 Abstract(Memory History)模式或其他 Vue-Router 模式(如 Hash 模式或 History 模式)。
何时使用Memory History模式(也叫abstract)?
使用 Abstract(Memory History)模式的适用场景主要包括以下几种:
服务器端渲染(Server-Side Rendering, SSR):当你在服务器端使用 Vue.js 渲染应用时,可以使用 Abstract 模式来处理路由,因为在服务器端环境中,浏览器相关的 API 和功能不可用。
原生应用:当你使用类似 NativeScript 或 Weex 的框架为移动设备构建原生应用时,由于应用不依赖于 Web 浏览器,可以使用 Abstract 模式处理路由。
测试环境:在进行单元测试或集成测试时,由于 Abstract 模式与浏览器环境无关,可以更容易地模拟导航和路由行为,提高测试的可靠性和便捷性。
非浏览器环境的应用:在某些特定的非浏览器环境(如 Electron 等)中,如果不需要使用浏览器的地址栏和历史 API,可以选择使用 Abstract 模式。
尽管 Abstract 模式在这些场景下非常有用,但在大多数 Web 应用中,更常见的是使用 Hash 模式或 History 模式,因为这两种模式允许用户直接访问特定 URL,以及使用浏览器的前进/后退按钮进行导航。
选择何时使用 Abstract(Memory History)模式取决于你的具体需求和应用场景。在评估这些因素后,你可以确定是否需要使用 Abstract 模式,或者选择其他 Vue-Router 模式。
总结:
综上所述,Hash History 和 Browser History 都是利用浏览器的 URL 来实现路由变化的,而 Memory History 不依赖 URL。
扩展一下:React-router也有相同的三种方式,完全一样的