Vue页面内容未保存时离开页面做弹框提示

16,168次阅读
没有评论

共计 2383 个字符,预计需要花费 6 分钟才能阅读完成。

一、背景

目标: 如果当前页面中有正在编辑中的内容,那么此时切换组件、跳转路由、关闭标签页、刷新页面,都会有离开确认提示,防止用户因误触导致填写的内容白费。

        后台管理系统中有许多需要填写的表单,弹窗方式的表单一般都会关掉或提交,而单页个面的表单,有时候会忘记暂存或提交,直接离开页面,导致千辛万苦填写的内容全部置空,这是非常不友好的!!!于是,需要实现一个功能: 如果当前页面中存在编辑中的内容,那么离开页面之前,要弹窗提示用户是否确认离开。

二、实现

1、路由守卫

        考虑到会有许许多多个编辑表单的单页面,所以将编辑状态存在 store 里,并通过路由守卫来判断是否弹出弹窗。

①store/router.js

const state = {
    // 定义全局的 isEditing 状态  
    isEditing: false  
}

const mutations = {
    // 定义修改 isEditing 状态的 mutation  
    SET_EDITING(state, isEditing) {state.isEditing = isEditing;}  
}

const actions = {setEditing({ commit}, data) {commit('SET_EDITING', data)
    }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

②路由守卫

import router from '../router'
import store from '../store'
import {MessageBox} from 'element-ui'
// 其它......

router.beforeEach(async(to, from, next) => {
    // 其它......
    if(!store.state.router.isEditing){ // 页面中无正在编辑内容
      await routerPermission(to, from, next)
    }else{// 页面中含有正在编辑内容

      MessageBox.confirm('您所做的更改暂未保存,确认离开页面?', '温馨提示', {  
        confirmButtonText: '离开',  
        cancelButtonText: '取消',  
        type: 'warning'  
      })  
      .then(async() => {store.commit('router/SET_EDITING', false)
        // 用户点击了确认,执行跳转 ==> 进入页面权限判断
        await routerPermission(to, from, next)
      })  
      .catch(() => {  
        // 用户点击了取消或关闭了对话框,阻止路由跳转  
        next(false); // 传入 false 来取消导航  
      });  


    }
    // 其它......
})

        通过这种全局的方式,可以在任何需要有这种判断的地方让 isEditing 变成 true 即可。下面是一个例子:

    isEditProp(newVal) {
      this.isEdit = newVal
      if(newVal===false){this.$emit('update:showEdit', false)
      }
      // 如果是整个表单一次性提交,则编辑状态下离开页面需要提示
      if(this.isAllAtOnce){this.$store.commit('router/SET_EDITING', newVal)
      }
    }

2、关闭标签页 / 刷新页面提示

        如果用户填写一半,不小心关闭标签页或者刷新页面,也会导致表单清空,这也是一种很糟糕的情况,所以,我们还需要一个关闭标签页提示。

  mounted() {window.addEventListener('beforeunload', e => this.beforeunloadHandler(e))
  },
  beforeDestroy() {window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e))
  },
  methods: {beforeunloadHandler(e) {this._beforeUnload_time = new Date().getTime()
      e = e || window.event
      if (e && this.$store.state.router.isEditing) {e.returnValue = '关闭提示'}
      return '关闭提示'
    },
  }

 3、组件切换

          对于 tabs 页面,切换视图并不会引起路由变化,所以路由守卫就不起作用了,这个时候,我们就要在组件切换之前进行提示。

①给 el-tabs 绑定一个事件:before-leave=”confirmLeave”

  
   ......
  

Vue 页面内容未保存时离开页面做弹框提示

②写提示方法

  methods: {async confirmLeave(pane){if(pane!=='flimLibrary' && this.$store.state.router.isEditing){
        return await this.$confirm('您所做的更改暂未保存,确认离开页面??', '温馨提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        .then(() => {this.$store.commit('router/SET_EDITING', false)
          this.$emit('update:actived', pane)
          this.isIgnore = true
          return true
        })
        .catch(() => {
          this.isIgnore = false
          return reject()})
      }
    }
  },

        这样处理之后就成功实现了预期的效果啦!

三、效果

①切换组件 / 跳转路由

Vue 页面内容未保存时离开页面做弹框提示

②关闭标签页

Vue 页面内容未保存时离开页面做弹框提示

③刷新页面

原文地址: Vue 页面内容未保存时离开页面做弹框提示

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-10-29发表,共计2383字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)