vue-router项目实战总结
今天来谈谈vue项目{vue,vue-router,component}三大神将之一的vue-router。作为我们前后端分离很重要的实践之一,router帮我们完成了SPA应用间的页面跳转。
并且,配合axios这样的第三方库,我们可以实现配合后台接口的拦截器功能。
对于一个小型项目而言,router这个文件夹里面就包含了一个router.js就足够了,
但是,当我们的页面比较多的时候,我们就需要分出两个文件出来:一个定义我们的路由和组件,另一个实例化组件,并将路由挂载到vue的实例上。
基本的用法就不多赘述,大家可以看vue-router的官网,认真过一遍的话,基本使用肯定没什么问题。
1.为什么我的路由不起作用?
这里有个非常重要的一点就是当我们去构造VueRouter的实例的时候,传入的参数的问题。
import routes from '@/router/router'
const router = new VueRouter({
  routes // (ES6语法)相当于 routes: routes
})
new Vue({
  router
}).$mount('#app')
如果你这里引入的不是routes,你就要按照下面的方式来写。
import vRoutes from '@/router/router'
const router = new VueRouter({
  routes :vRoutes
})
new Vue({
  router
}).$mount('#app')
2.在路由中基于webpack实现组件的懒加载
对于我们的vue项目,我们基本都是运用webpack打包的,如果没有懒加载,打包后的文件将会异常的大,造成首页白屏,延时严重,不利于用户体验,而运用懒加载则可以将页面进行划分,webpack将不同组件打包成很多个小的js文件。需要的时候再异步加载,优化用户的体验,换而言之,有的页面可能100个用户只有一两个会进去,何必把流量花在它身上。
import App from '@/App.vue'
const index = r  => require.ensure([], () => r(require('@/pages/index/index')), 'index')
export default [{
  path: '/',
  component: App,
  children: [
    {
       path: '/index',
       name:'index',
       component: index
    }]
}]
如果某个组件包含了嵌套路由,我们也可以将两个路由打包到一个js chunk中。
// 这两条路由被打包在相同的块中,访问任一路由都会延迟加载该路由组件
const orderUser= r => require.ensure([], () => r(require('@/pages/order/user')), 'order')
const payRecord= r => require.ensure([], () => r(require('@/pages/order/payRecord')), 'order')
3.router的模式
对于浏览器,我们的router分为两种模式。
1.hash模式(默认)
按照一个uri的基本结构来说,hash模式就是在一个基本的URI的片段进行的处理。如果抛开SPA的话,比较常见的应用场景就是我们在做pc商城的时候,会有比如说:商品详情,评论,商品参数这样的tab切换,就可以使用a标签配合id使用,加上一点运动的特效,效果甚佳。

这也是router默认使用的路由方式。不过,这种方式有一个弊端,就是在接入第三方的支付的时候,我们传入一个url给到第三方支付作为回调地址,但是在支付完成以后,有的第三方支付会把我们的#作为一个截取符号,仅保留第一个#符号前面的url内容,后面再添加相应的回调参数。导致支付完成以后无法跳转到相应的支付页面
传入的url:
http://xx.xx.com/#/pay/123
回调后的地址:
http://xx.xx.com/pay/123?data=xxxxx%xxxx
2.history模式
还有一种就是history的模式。它是使用h5的history.pushState来完成URL的跳转的。使用这种方式来处理跳转的好处就是,url和我们平常看到的没有什么区别。和hash模式作比较的话就是没有了#。不过使用history模式,我们在后台也要去做相应的处理,因为如果直接去访问一个地址,例如http://www.xxxx.com/user/id的时候,如果后端没有配置的时候,后端就会返回404页面。
4.router-link在循环中this.参数名=undefined
<router-link>组件是我们在view层中需要用到的跳转组件。它替代了<a>标签需要做的事情,并且帮助我们做了更多的事情。
无论是 h5 history 模式还是 hash 模式,它的表现行为一致,所以,当你要切换路由模式,或者在 IE9 降级使用 hash 模式,无须任何变动。
在 HTML5 history 模式下,
router-link会守卫点击事件,让浏览器不再重新加载页面。当你在 HTML5 history 模式下使用
base选项之后,所有的to属性都不需要写(基路径)了。
不过当我们在v-for的循环中使用了router-link的时候,一般来说,我们需要取的都是循环里的值,通过定义的item.xxx就可以取到。如果说需要取一个我们在data中定义的值的时候,我们是通过this.foo来取呢?还是通过foo来取呢?还是都可以?
这里的话,我们是不能通过this.foo来取的,因为这里的this,不再是指向vue的实例了,而是指向了[object Window]。所以用this.foo来取的话,其实是undefined.
 <router-link tag="li" :to="{path:`/user/${item.userID}`}" v-for="(item, index) in userList" :key="index">
     //含有固定的值
    <p>{{this.foo}}</p>
    <p>{{foo}}</p>
 </router-link>
data(){
    return {
        foo:'bar',
    }
}
4.vue-router配合axios的使用
初次接触拦截器这个概念是在java中,通过拦截器,我们可以对用户的登录状态进行更加粒度的操作。而对于一个SPA的应用来说,没有了后台路由的介入,我们就需要在前端实现一套自己的登录状态的管理机制。
最直观的一点就是,通过用户的token来判断用户是否登录?
router.beforeEach((to, from, next) => {
  const NOW = new Date().getTime();
  if (to.matched.some(r => r.meta.requireAuth)) {
    if(NOW > store.state.deadLine){
      store.commit('CLEAR_USERTOKEN')
    }
    if (store.state.message.login === true) {
      next();
    }
    else {
      next({
        path: '/login',
        query: {redirect: to.fullPath}
      })
    }
  }
  else {
    next();
  }
})
上面的代码中,我们通过vue-router中的全局守卫,在导航触发的时候大致做了如下几件事:
(1)判断导航的页面是否需要登录
(2)超过登录持久期限,清除持久化的登录用户token
(3)没有超过登录期限,判断是否登录状态
(4)没登录,重定向到登录页面
但是,仅仅这样是不够的。因为用户直接不正常注销而直接后台运行网页是很正常的事情,这就导致虽然token是存在的,但是对于后台而言,这个token是无效的,过期的了。所以,我们需要axios配合后台给出的状态码来完善我们的拦截器。
import router from '@/router/routes' axios.interceptors.response.use(
success => {
switch (success .code) {
case -100:
router.replace({
path: 'login',
query: {redirect: router.currentRoute.fullPath}
})
console.warn('注意,登录已过期!')
break;
}
return success;
},
error => {
switch (error.code) {
case 404:
console.warn('请求地址有误或者参数错误!')
break;
}
return Promise.reject(error.response.data)
});
通过后端给到的登录过期状态码,这里以-100为例,我们可以用axios的响应拦截器实现,当我们的token过期的时候,我们将页面重定向到登录页面去。
5.巧用replace替换push
在项目中,我有的同事就是一直this.$router.push(...),从开始push到结尾。
碰到有的页面,比如说,在选择地址的时候需要知道用户当前所在的城市,如果没有的话,就是重定向到城市列表页面去手动选取。选择完成以后再回到选择地址的页面,如果一直使用push的话,点击选择地址的后退时,就会回退到城市列表页。然后造成页面间的死循环。
这里如果使用replace来操作就没有什么问题了,问题就是我们不应该让城市列表页出现在我们的浏览历史里面。
vue-router项目实战总结的更多相关文章
- 新书上线:《Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统》,欢迎大家买回去垫椅子垫桌脚
		
新书上线 大家好,笔者的新书<Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统>已上线,此书内容充实.材质优良,乃家中必备垫桌脚 ...
 - Vue公司项目实战步骤
		
一.无权限,无验证的Vue项目 1.打好HTML+CSS+JS基础,及<Vue 2.0 实战> 2.编写用mock设计的案例: 3.将以上案例的后台用C#改写: 二.带安全验证的Vue项目 ...
 - 深入浅出的webpack构建工具--webpack4+vue+router项目架构(十四)
		
阅读目录 一:vue-router是什么? 二:vue-router的实现原理 三:vue-router使用及代码配置 四:理解vue设置路由导航的两种方法. 五:理解动态路由和命名视图 六:理解嵌套 ...
 - vue+webpack项目实战
		
概述 -- 项目中会用到的插件 vue-router vue-resource 打包工具 webpack 依赖环境 node.js start 安装vue开发的模板 # 全局安装 vue-cli $ ...
 - vue全家桶(Vue+Vue-router+Vuex+axios)(Vue+webpack项目实战系列之二)
		
Vue有多优秀搭配全家桶做项目有多好之类的咱就不谈了,直奔主题. 一.Vue 系列一已经用vue-cli搭建了Vue项目,此处就不赘述了. 二.Vue-router Vue的路由,先献上文档(http ...
 - 第10章-Vue.js 项目实战
		
一.本节内容 掌握项目环境中路由的配置方法 ***** 熟练掌握编写单文件组件的编写 *** 能够使用swiper.js进行轮播图组件的封装 能够使用axios进行数据请求 二.webpack项目的目 ...
 - vue组件(Vue+webpack项目实战系列之三)
		
组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.特别对于大型应用开发来说,尽量组件化,并且先造好轮子库,不要重复去写组件,这会显著提升项目 ...
 - Vue.js项目实战-多语种网站(租车)
		
首先来看一下网站效果,想写这个项目的读者可以自行下载哦,地址:https://github.com/Stray-Kite/Car: 在这个项目中,我们主要是为了学习语种切换,也就是右上角的 中文/En ...
 - Vue.js项目实战-打造线上商城
		
首先上一下完成后的效果: 首页: 商品详情页: 购物车页(其实还有个订单页,只是和购物车页基本类似,所以就不截图啦): 开始项目: 由于涉及的是前后端分离,所以我们的后台数据就模拟存储于浏览器端(co ...
 - Ant Design Vue Pro 项目实战-项目初始化(一)
		
写在前面 时间真快,转眼又是新的一年.随着前后端技术的不断更新迭代,尤其是前端,在目前前后端分离开发模式这样的一个大环境下,交互性.兼容性等传统的开发模式已经显得有些吃力.之前一直用的是react,随 ...
 
随机推荐
- redis字符串结构
			
1.字符串SDS struct sdshdr { // buf 已占用长度 int len; // buf 剩余可用长度 int free; // 实际保存字符串数据的地方 // 利用c99(C99 ...
 - PCL+VS2010环境配置
			
PCL+VS2010环境配置 我本是效率至上的Linux党,但是PCL在Ubuntu下配置了几次都失败,不得不选择Windows 1.下载 http://go.rritw.com/www.pointc ...
 - NB-IoT物联网,来了
			
日前,深圳移动联合华为公司在深圳市福田.前海及盐田区域部署NB-IoT/LTE融合站点130余个,完成NB-IoT系统关键技术验证和组网技术验证,已初步形成NB-IoT试商用条件.深圳移动后续将在深圳 ...
 - DIV+CSS特殊符号的处理方法
			
: :; ;< <= => >? ?@ @^ ^_ _` `{ {| |} }~ ~--- ...
 - .bash_profile 加载
			
1.Debian默认的shell是Bash, 1.1 命令行 和 ssh 登录 ,首先读入 /etc/profile,这是对所有用户都有效的配置:然后依次寻找下面三个文件,这是针对当前用户的配置. ~ ...
 - Nginx的知识分享,继续上次的分享
			
5. Nginx配置文件精讲二 #这里为后端服务器wugk应用集群配置,根据后端实际情况修改即可,tdt_wugk为负载均衡名称,可以任意指定 #但必须跟vhosts.conf虚拟主机的pass段一致 ...
 - 关于mui header在手机上运行丢失问题
			
并不需要换header, 只需要把引用的例子自带的CSS文件 app.css.里的两个样式:.mui-plus.mui-android header.mui-bar {display: none;}. ...
 - 05.haproxy+mysql负载均衡 整合 redis集群+ssm
			
本篇重点讲解haproxy+mysql负载均衡,搭建完成后与之前搭建的redis+ssm进行整合 (注:这里用到了两台mysql数据库,分别安装两台虚拟机上,已经成功实现主主复制,如果有需要,请查看我 ...
 - CS Round#50 D min-races
			
Min Races Time limit: 1000 msMemory limit: 256 MB In a racing championship there are N racing driv ...
 - 鼠标悬停,图片放大 CSS实现
			
因为最近做的项目刚好用到了这个实现,分享出来 class=enlarge 为div标签的class div img 为标签 .enlarge div img:hover{ transform: s ...