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 相关文章推荐
使用jQuery轻松实现Ajax的实例代码
Aug 16 Javascript
jquery弹出框的用法示例(一)
Aug 26 Javascript
jquery easyui combox一些实用的小方法
Dec 25 Javascript
js中substring和substr的定义和用法
May 05 Javascript
利用React-router+Webpack快速构建react程序
Oct 27 Javascript
js入门之Function函数的使用方法【新手必看】
Nov 22 Javascript
js 中文汉字转Unicode、Unicode转中文汉字、ASCII转换Unicode、Unicode转换ASCII、中文转换
Dec 06 Javascript
jQuery插件echarts去掉垂直网格线用法示例
Mar 03 Javascript
vue ssr+koa2构建服务端渲染的示例代码
Mar 23 Javascript
基于VUE实现判断设备是PC还是移动端
Jul 03 Javascript
vue 需求 data中的数据之间的调用操作
Aug 05 Javascript
vue实现折线图 可按时间查询
Aug 21 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
仿AS3实现PHP 事件机制实现代码
2011/01/27 PHP
php中取得URL的根域名的代码
2011/03/23 PHP
PHP递归的三种常用方式
2019/02/28 PHP
JS启动应用程序的一个简单例子
2008/05/11 Javascript
JQuery中$.ajax()方法参数详解及应用
2013/12/12 Javascript
使用jQuery实现input数值增量和减量的方法
2015/01/24 Javascript
使用命令对象代替switch语句的写法示例
2015/02/28 Javascript
js完美实现@提到好友特效(兼容各大浏览器)
2015/03/16 Javascript
javascript中attachEvent用法实例分析
2015/05/14 Javascript
jQuery增加自定义函数的方法
2015/07/18 Javascript
jQuery实现的图文高亮滚动切换特效实例
2015/08/10 Javascript
jQuery 3 中的新增功能汇总介绍
2016/06/12 Javascript
BootStrap+Angularjs+NgDialog实现模式对话框
2016/08/24 Javascript
JS中传递参数的几种不同方法比较
2017/01/20 Javascript
JS实现json的序列化和反序列化功能示例
2017/06/13 Javascript
Vue中v-for的数据分组实例
2018/03/07 Javascript
Vue项目安装插件并保存
2019/01/28 Javascript
python进程管理工具supervisor使用实例
2014/09/17 Python
pymongo实现多结果进行多列排序的方法
2015/05/16 Python
Python求算数平方根和约数的方法汇总
2016/03/09 Python
Python单链表简单实现代码
2016/04/27 Python
python实现解数独程序代码
2017/04/12 Python
python实现输入数字的连续加减方法
2018/06/22 Python
python 进程间数据共享multiProcess.Manger实现解析
2019/09/23 Python
Python中flatten( ),matrix.A用法说明
2020/07/05 Python
Richards网上商店:当代时尚,遍布巴西
2019/11/03 全球购物
奥林匹亚体育:Olympia Sports
2020/12/30 全球购物
幼儿园儿童节活动主持词+串词大全
2014/03/21 职场文书
《梅花魂》教学反思
2014/04/30 职场文书
爱护公共设施倡议书
2014/08/29 职场文书
关于国庆节的演讲稿
2014/09/05 职场文书
大学毕业典礼演讲稿
2014/09/09 职场文书
2014和解协议书范文
2014/09/15 职场文书
简易离婚协议书(范本)
2014/10/25 职场文书
优秀共产党员主要事迹材料
2015/11/05 职场文书
python中__slots__节约内存的具体做法
2021/07/04 Python