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 相关文章推荐
js innerHTML 的一些问题的解决方法
Jun 22 Javascript
Jquery AJAX 框架的使用方法
Nov 03 Javascript
SlideView 图片滑动(扩展/收缩)展示效果
Aug 01 Javascript
javascript显示用户停留时间的简单实例
Aug 05 Javascript
jQuery中filter()和find()的区别深入了解
Sep 25 Javascript
JavaScript实现url地址自动检测并添加URL链接示例代码
Nov 12 Javascript
js检验密码强度(低中高)附图
Jun 05 Javascript
JQuery select(下拉框)操作方法汇总
Apr 15 Javascript
JQuery点击事件回到页面顶部效果的实现代码
May 24 Javascript
原生JS实现图片轮播效果
Dec 26 Javascript
移动端Ionic App 资讯上下循环滚动的实现代码(跑马灯效果)
Aug 29 Javascript
小程序实现长按保存图片的方法
Dec 31 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
全国FM电台频率大全 - 13 福建省
2020/03/11 无线电
使用JSON实现数据的跨域传输的php代码
2011/12/20 PHP
smarty巧妙处理iframe中内容页的代码
2012/03/07 PHP
PHP中CURL方法curl_setopt()函数的参数分享
2013/01/19 PHP
PHP中soap的用法实例
2014/10/24 PHP
PHP使用xpath解析XML的方法详解
2017/05/20 PHP
网站页面自动跳转实现方法PHP、JSP(下)
2010/08/01 Javascript
ASP.NET jQuery 实例8 (动态添加内容到DropDownList)
2012/02/03 Javascript
3分钟写出来的Jquery版checkbox全选反选功能
2013/10/23 Javascript
JS拉起或下载app的实现代码
2017/02/22 Javascript
vue vuex vue-rouert后台项目——权限路由(适合初学)
2017/12/29 Javascript
js 将canvas生成图片保存,或直接保存一张图片的实现方法
2018/01/02 Javascript
vue实现模态框的通用写法推荐
2018/02/26 Javascript
vue2.0 axios跨域并渲染的问题解决方法
2018/03/08 Javascript
vue中post请求以a=a&amp;b=b 的格式写遇到的问题
2018/04/27 Javascript
Vue2.0 实现歌手列表滚动及右侧快速入口功能
2018/08/08 Javascript
JS+HTML5 Canvas实现简单的写字板功能示例
2018/08/30 Javascript
localstorage实现带过期时间的缓存功能
2019/06/28 Javascript
layer.open 子页面弹出层向父页面传输数据的例子
2019/09/26 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
2019/11/17 Javascript
Python中利用sorted()函数排序的简单教程
2015/04/27 Python
Python实现的下载网页源码功能示例
2017/06/13 Python
python 上下文管理器使用方法小结
2017/10/10 Python
Python3编码问题 Unicode utf-8 bytes互转方法
2018/10/26 Python
Python 做曲线拟合和求积分的方法
2018/12/29 Python
详解django中url路由配置及渲染方式
2019/02/25 Python
Python爬虫beautifulsoup4常用的解析方法总结
2019/02/25 Python
python遍历文件目录、批量处理同类文件
2019/08/31 Python
python logging 重复写日志问题解决办法详解
2020/08/04 Python
HTML5 manifest离线缓存的示例代码
2018/08/08 HTML / CSS
经济学博士求职自荐信范文
2013/11/23 职场文书
任命书格式
2014/06/05 职场文书
2016年社区创先争优活动总结
2016/04/05 职场文书
史上最全书信经典范文大全(建议收藏)
2019/07/10 职场文书
CSS3点击按钮圆形进度打钩效果的实现代码
2021/03/30 HTML / CSS
苹果M1芯片安装nginx 并且部署vue项目步骤详解
2021/11/20 Servers