vue-router项目实战总结篇


Posted in Javascript onFebruary 11, 2018

今天来谈谈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项目实战总结,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
不一样的文字闪烁 轮番闪烁
Nov 11 Javascript
js href的用法
May 13 Javascript
JS拖动技术 关于setCapture使用
Dec 09 Javascript
jQuery选择id属性带有点符号元素的方法
Mar 17 Javascript
JS小数转换为整数的方法分析
Jan 07 Javascript
手把手搭建安装基于windows的Vue.js运行环境
Jun 12 Javascript
Vue学习笔记进阶篇之多元素及多组件过渡
Jul 19 Javascript
关于echarts在节点显示动态数据及添加提示文本所遇到的问题
Apr 20 Javascript
vue input 输入校验字母数字组合且长度小于30的实现代码
May 16 Javascript
vuex管理状态 刷新页面保持不被清空的解决方案
Nov 11 Javascript
JS造成内存泄漏的几种情况实例分析
Mar 02 Javascript
微信小程序自定义纯净模态框(弹出框)的实例代码
Mar 09 Javascript
vue项目实战总结篇
Feb 11 #Javascript
在 Angular中 使用 Lodash 的方法
Feb 11 #Javascript
Material(包括Material Icon)在Angular2中的使用详解
Feb 11 #Javascript
原生JS实现循环Nodelist Dom列表的4种方式示例
Feb 11 #Javascript
Vue实现点击后文字变色切换方法
Feb 11 #Javascript
Vue-cli中为单独页面设置背景色的实现方法
Feb 11 #Javascript
vue刷新和tab切换实例
Feb 11 #Javascript
You might like
Web程序工作原理详解
2014/12/25 PHP
PHP mysql事务问题实例分析
2016/01/18 PHP
JavaScript实现删除电脑的关机键
2016/07/26 PHP
关于二级域名下使用一级域名下的COOKIE的问题
2011/11/07 Javascript
qTip2 精致的基于jQuery提示信息插件
2012/02/17 Javascript
Jquery带搜索框的下拉菜单
2013/05/06 Javascript
抛弃Nginx使用nodejs做反向代理服务器
2014/07/17 NodeJs
JavaScript数据结构与算法之栈与队列
2016/01/29 Javascript
JavaScript事件详细讲解
2016/06/27 Javascript
Bootstrap登陆注册页面开发教程
2016/07/12 Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
2016/09/21 Javascript
EasyUI Combobox设置默认值 获取text的方法
2016/11/28 Javascript
vue通过watch对input做字数限定的方法
2017/07/13 Javascript
jQuery实现拼图小游戏(实例讲解)
2017/07/24 jQuery
angularjs实现柱状图动态加载的示例
2017/12/11 Javascript
使用Angular CLI快速创建Angular项目的一些基本概念和写法小结
2018/04/22 Javascript
JS/HTML5游戏常用算法之碰撞检测 像素检测算法实例详解
2018/12/12 Javascript
vue项目中实现的微信分享功能示例
2019/01/21 Javascript
深入探讨JavaScript的最基本部分之执行上下文
2019/02/12 Javascript
python使用PIL和matplotlib获取图片像素点并合并解析
2019/09/10 Python
从训练好的tensorflow模型中打印训练变量实例
2020/01/20 Python
浅谈tensorflow中Dataset图片的批量读取及维度的操作详解
2020/01/20 Python
pytorch中的inference使用实例
2020/02/20 Python
Python importlib动态导入模块实现代码
2020/04/16 Python
Python 多进程、多线程效率对比
2020/11/19 Python
python线程优先级队列知识点总结
2021/02/28 Python
美国嘻哈文化生活方式品牌:GLD
2018/04/15 全球购物
Nanushka官网:匈牙利服装品牌
2019/08/14 全球购物
最新计算机专业自荐信
2013/10/16 职场文书
电气专业应届生求职信
2013/11/01 职场文书
《高尔基和他的儿子》教学反思
2014/04/09 职场文书
竞聘自述材料
2014/08/25 职场文书
民政局标准版离婚协议书
2014/12/01 职场文书
会计求职简历自我评价
2015/03/10 职场文书
python机器学习Github已达8.9Kstars模型解释器LIME
2021/11/23 Python