我们先来说vue-route的两种模式以及区别
为什么要有hash和history?
对于Vue这类渐进式前端开发框架,为了构建spA(单页面应用),需要引入前端路由系统,这也就是vue-route存在的意义,前端路由的核心,就在于------改变视图的时不会向后端发出请求.为了达到这个目的,浏览器当前提供了以下两种支持:
1:hash----即地址栏URL中的#符号
比如这个 URL:http://www.abc.com/#/hello
,hash 的值为 #/hello
。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面
2:history —— 利用了 HTML5 History Interface 中新增的 pushState()
和 replaceState()
方法
这两个方法应用于浏览器的历史记录栈,在当前已有的 back
、forward
、go
的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
使用场景
一般场景下,hash 和 history 都可以,除非你更在意颜值,# 符号夹杂在 URL 里看起来确实有些不太美丽。
如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成
URL 跳转而无须重新加载页面。
vue-route的声明式和编程式的导航
声明式导航:
声明式导航是指通过点击链接实现导航的方式,比如a标签和router-link标签.
<div id="app">
<router-link :to="{ name:'user',params:{id:3} }">login3</router-link>
<router-link :to="{ name:'user',params:{id:4} }">login4</router-link>
<router-link :to="{ name:'user',params:{id:5} }">login5</router-link>
<router-link to="/register">register</router-link>
<!-- 路由占位符-->
<router-view></router-view>
</div>
编程式导航
编程式导航是指调用了JavaScript的API实现导航的方式
下面介绍两个常用的导航API:
1:this.$router.push('地址')
代码展示:
在组件模板中插入一个按钮,给它一个点击事件,同时在template后面添加methods,为事件写入this.$router.push()
const login = {
props: ['name', 'age','id'],
template: `
<div>
<h1>登录组件---id为:{{ id }}----姓名为:{{ name }}----年龄为:{{ age }}</h1>
<button @click="goRegister">跳转到注册界面</button>
</div>
`,
methods:{
goRegister(){
this.$router.push('/register');
}
}
};
页面显示效果:
2:this.$router.go(n)
代码展示:
在组件模板中插入一个按钮,给它一个点击事件,同时在template后面添加methods,为事件写入this.$router.go(-1)
const register = {
template: `
<div>
<h1>注册组件</h1>
<router-link to="/register/tab1">tab1组件</router-link>
<router-link to="/register/tab2">tab2组件</router-link>
<router-view></router-view>
<button @click="goBack">回退到上一个页面</button>
</div>
`,
methods:{
goBack(){
this.$router.go(-1);
}
}
};
页面展示效果:
vue-router传参方式:
动态路由传参
动态路径参数,使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到this.r o u t e . p a r a m s , 可 以 在 每 个 组 件 内 使 用 。 你 可 以 在 一 个 路 由 中 设 置 多 段 “ 路 径 参 数 ” , 对 应 的 值 都 会 设 置 到 route.params,可以在每个组件内使用。你可以在一个路由中设置多段“路径参数”,对应的值都会设置到route.params,可以在每个组件内使用。你可以在一个路由中设置多段“路径参数”,对应的值都会设置到route.params中。例如
在router文件夹下的index.js李配置动态路由
goods组件里
在浏览器地址栏中输入(/goods/123)
深入了解路由传参方法
现有如下场景 点击当前也的摸个按钮跳转到另一个页面去,并将某个值带过去
第一种方法:params传参,url中会显示参数,页面刷新数据不会丢失.
需要在routers里对应路由配置下:
可以看出需要在path中添加/:id来对应 r o u t e r . p u s h 中 p a t h 携 带 的 参 数 。 在 子 组 件 中 可 以 使 用 t h i s . router.push 中path携带的参数。在子组件中可以使用this.router.push中path携带的参数。在子组件中可以使用this.route.params.id来获取传递的参数值。
第二种方法:params传参,url中不会显示参数, 页面刷新数据会丢失。
定义路由时添加name属性给映射的路径取一个别名,在router文件夹的index.js文件修改router如下:
在父路由组件上使用router-link进行路由导航,使用 <router-link :to="{name:‘home’,params:{id:001}} > 形式传递参数。注意 ': to= ’ 前面的冒号,childOne.vue组件修改如下:
子路由组件页面获取父路由传参方式不变,reg.vue 文件如下:
上述这种利用params不显示url传参的方式会导致在刷新页面的时候,传递的值会丢失。
params与query传参有何区别?
query 传参配置的是path,而params传参配置的是name,在params中配置path无效。query在路由配置不需要设置参数,而params必须设置。query传递的参数会显示在地址栏中,params传参刷新会无效,但是query会保存传递过来的值,刷新不变 。
vue-router的优点和缺点:
优点: 良好的交互体验,用户不需要刷新页面,页面显示流畅, 良好的前后端工作分离模式,减轻服务器压力,
缺点: 不利于SEO,初次加载耗时比较多
2、hash模式
vue-router默认的是hash模式,使用URL的hash来模拟一个完整的URL,于是当URL改变的时候,页面不会重新加载,也就是单页应用了,当#后面的hash发生变化,不会导致浏览器向服务器发出请求,浏览器不发出请求就不会刷新页面,并且会触发hasChange这个事件,通过监听hash值的变化来实现更新页面部分内容的操作
对于hash模式会创建hashHistory对象,在访问不同的路由的时候,会发生两件事:
HashHistory.push()将新的路由添加到浏览器访问的历史的栈顶,和HasHistory.replace()替换到当前栈顶的路由
3、history模式
主要使用HTML5的pushState()和replaceState()这两个api来实现的,pushState()可以改变url地址且不会发送请求,replaceState()可以读取历史记录栈,还可以对浏览器记录进行修改
window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)
区别:
前面的hashchange,你只能改变#后面的url片段。而pushState设置的新URL可以是与当前URL同源的任意URL。
history模式则会将URL修改得就和正常请求后端的URL一样,如后端没有配置对应/user/id的路由处理,则会返回404错误,需要后端在服务端设置,如果 URL 匹配不到任何静态资源,则返回同一个 index.html 页面,这个页面就是你 app 依赖的页面