VUE 离开页面路由拦截

业务场景

  • 在页面内容被编辑后,用户跳转其他路由,需要提示用户:当前页面有改动,确认离开后再进行跳转,以防编辑数据丢失。

    代码

beforeRouteLeave (to, from, next) {
     this.targetName = to.name  // 提示框点击确认后跳转的 路由
   if (this.checkEdit()) { // 是否对页面进行了编辑
      this.dialogVisible = true    // 打开离开页面的提示框
      next(false)
    } else {
      this.dialogVisible = false
      next()
    }
}
  • VUE 提供一个钩子函数 beforeRouteLeave, 离开当前路由时会先触发该函数,当然也有beforeRouteEnter,进入路由前先触发该函数。

  • to: 目标路由的相关信息 对象
  • from:当前路由的相关信息 对象
  • next:实行跳转的 函数。传入false,不进行跳转。

    检测页面是否编辑

    我的思路是在页面初始化时,设置一个对象保存旧有的值。例如在编辑页面初始化编辑数据时:

  data () {
        return: {
            formData: {},
            oldData: {}
      }
  },
  mounted () {
        init() {
            axios.get(‘/example).then(res => {   // 这里就简写了
                Object.assign(this.oldData, res.data) //这里对已有的编辑数据进行保存
            this.formData = res.data     // 这里正常回显
         })
      }
  }

进行存储后即可保留用户编辑页面时的初始状态。然后离开页面时进行校验:

  checkEdit () {
        for (let key in this.oldValObj) {
        if (this.oldValObj[key] != this.formData[key]) {
          return true
        }
      }
      return false
  }



至此,一般情况下的编辑改动即完成了。
但如果你获得表单数据,是一个对象内还包含对象的数据,
Object.assign() 就会有错了,它仅支持浅拷贝。我们此时需要使用的是深复制方法了,如下:

    deepClone (obj) {
   let objClone = Array.isArray(obj) ? [] : {};
   if(obj && typeof obj === ‘object’){
    for(let key in obj){
      // 判断是不是自有属性,而不是继承属性
      if(obj.hasOwnProperty(key)){
        //判断ojb子元素是否为对象或数组,如果是,递归复制
        if(obj[key]&&typeof obj[key] === ‘object’){
          objClone[key] = this.deepClone(obj[key]);
        }else{
          //如果不是,简单复制
          objClone[key] = obj[key];
        }
      }
    }
  }
  return objClone;
 }

这种情况下,checkEdit也需要调整。

/*   @param x {Object} 对象1
 *   @param y {Object} 对象2
 *   @return {Boolean} true 为相等,false 为不等
 */
checkEdit(x, y) { // 指向同一内存时
  if (x === y) {
    return true;
  } else if ((typeof x == "object" && x != null) && (typeof y == "object" && y != null)) {
    if (Object.keys(x).length != Object.keys(y).length) {
      return false;
    }
    for (var prop in x) {
      if (y.hasOwnProperty(prop)) {
        if (!deepEqual(x[prop], y[prop])) {
          return false;
        }
      }
      else {
        return false;
      }
    }
    return true;
  } else {
    return false;
  }
}

总结:

对于一般的表单问题,能确定数据对象中不会包含对象的情形时,数据比较简单,使用第一种简易版本会方便调试。数据类型比较复杂的情况,就应该考虑深复制,深对比的思路了。

原文地址:https://www.cnblogs.com/miku561/p/12163189.html

时间: 2024-11-10 12:08:11

VUE 离开页面路由拦截的相关文章

Vue+axios 实现http拦截及路由拦截

现如今,每个前端对于Vue都不会陌生,Vue框架是如今最流行的前端框架之一,其势头直追react.最近我用vue做了一个项目,下面便是我从中取得的一点收获. 基于现在用vue+webpack搭建项目的文档已经有很多了,我就不再累述了. 技术栈 vue2.0 vue-router axios 拦截器 首先我们要明白设置拦截器的目的是什么,当我们需要统一处理http请求和响应时我们通过设置拦截器处理方便很多. 这个项目我引入了element ui框架,所以我是结合element中loading和me

【转】vue+axios 前端实现登录拦截(路由拦截、http拦截)

一.路由拦截 登录拦截逻辑 第一步:路由拦截 首先在定义路由的时候就需要多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录.如果用户已经登录,则顺利进入路由, 否则就进入登录页面. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const routes = [     {         path: '/',         name: '/',         component: Index     },

vue+axios 前端实现登录拦截(路由拦截、http拦截)

一.路由拦截 登录拦截逻辑 第一步:路由拦截 首先在定义路由的时候就需要多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录.如果用户已经登录,则顺利进入路由, 否则就进入登录页面. const routes = [     {         path: '/',         name: '/',         component: Index     },     {         path: '/repository',         name: 'rep

vue+axios完美实现前端路由拦截

一.路由拦截 1.首先在router的index.js里配置一个自定义字段requireAuth,用该字段来判断进入该路由是否需要登录.如果已经登陆则进入该路由,反之则进入登录页面. 如图是路由配置: 2.在main.js里面利用vue-router的beforeEach钩子函数对路由进行判断. 实例代码如下所示: 解释下这段代码,当我们在登录的时候,利用sessionStorage保存了用户的token值,如果我们进入某一个需要登录的路由并且能够拿到token值的话,则可以直接next():反

vue 路由拦截器和请求拦截器

vue 拦截器 路由拦截器 已路由为导向 router.beforeEach((to,from,next)=>{ if(to.path=='/login' || localStorage.getItem('token')){ next(); }else{ alert('请重新登录'); next('/login'); } }) 请求拦截器 当发送请求时才会触发此功能 axios.interceptors.request.use(function (config) { let token = wi

vue 动态获取路由在对组件进行处理是报错,导致无法进入页面

vue 动态获取路由在对组件进行处理是报错,导致无法进入页面function filterAsyncRouter(asyncRouterMap) { //遍历后台传来的路由字符串,转换为组件对象const accessedRouters = asyncRouterMap.filter(route => { if (route.component) { if (route.component === 'Layout') {//Layout组件特殊处理 route.component = Layou

vue项目常见之五:路由拦截器(permission),导航守卫

// 处理路由拦截器 导航守卫 import router from '../router' import progresss from 'nprogress' import 'nprogress/nprogress.css' // 全局前置守卫 当 路由发生变化时 这个方法里的回调函数就会执行 router.beforeEach(function (to, from, next) { progresss.start() // 开启进度条 // 权限拦截 认为有token 让过去 没token不

Vue 2.0 路由全局守卫

路由跳转前做一些验证,比如登录验证,是网站中的普遍需求. 对此,vue-route 提供的 beforeRouteUpdate 可以方便地实现导航守卫(navigation-guards). 导航守卫(navigation-guards)这个名字,听起来怪怪的,但既然官方文档是这样翻译的,就姑且这么叫吧. 贴上文档地址:https://router.vuejs.org/zh-cn/advanced/navigation-guards.html 全局守卫 你可以使用 router.beforeEa

一个简单的react路由拦截

不同于vue,通过在路由里设置meta元字符实现路由拦截.react实现路由拦截的基本思路还是利用Route 的render函数.通过判断拦截条件(比如sessionID是否存在)来实现不同的组件的跳转,从而实习拦截. 接下来,我们实现一个简单的实例了解路由拦截的基本流程. 页面初次渲染的时候,需要我们进行登录.在这个首屏的页面里,我们放入一个链接.当点击链接,我们想进入我们的布局页面,(实际项目中是我们的后台).但是布局页面是不允许我们随意进入的.如果没有登录(真实项目中我们以sessioni