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


    一、背景

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

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

    二、实现

    1、路由守卫

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

    ①store/router.js

    1. const state = {
    2. // 定义全局的 isEditing 状态
    3. isEditing: false
    4. }
    5. const mutations = {
    6. // 定义修改 isEditing 状态的 mutation
    7. SET_EDITING(state, isEditing) {
    8. state.isEditing = isEditing;
    9. }
    10. }
    11. const actions = {
    12. setEditing({ commit }, data) {
    13. commit('SET_EDITING', data)
    14. }
    15. }
    16. export default {
    17. namespaced: true,
    18. state,
    19. mutations,
    20. actions
    21. }

    ②路由守卫

    1. import router from '../router'
    2. import store from '../store'
    3. import { MessageBox } from 'element-ui'
    4. // 其它......
    5. router.beforeEach(async(to, from, next) => {
    6. // 其它......
    7. if(!store.state.router.isEditing){ //页面中无正在编辑内容
    8. await routerPermission(to, from, next)
    9. }else{//页面中含有正在编辑内容
    10. MessageBox.confirm('您所做的更改暂未保存,确认离开页面?', '温馨提示', {
    11. confirmButtonText: '离开',
    12. cancelButtonText: '取消',
    13. type: 'warning'
    14. })
    15. .then(async() => {
    16. store.commit('router/SET_EDITING', false)
    17. // 用户点击了确认,执行跳转 ==> 进入页面权限判断
    18. await routerPermission(to, from, next)
    19. })
    20. .catch(() => {
    21. // 用户点击了取消或关闭了对话框,阻止路由跳转
    22. next(false); // 传入 false 来取消导航
    23. });
    24. }
    25. // 其它......
    26. })

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

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

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

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

    1. mounted() {
    2. window.addEventListener('beforeunload', e => this.beforeunloadHandler(e))
    3. },
    4. beforeDestroy() {
    5. window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e))
    6. },
    7. methods: {
    8. beforeunloadHandler(e) {
    9. this._beforeUnload_time = new Date().getTime()
    10. e = e || window.event
    11. if (e && this.$store.state.router.isEditing) {
    12. e.returnValue = '关闭提示'
    13. }
    14. return '关闭提示'
    15. },
    16. }

     3、组件切换

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

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

    1. :value="actived"
    2. class="tabs-container"
    3. v-bind="$attrs"
    4. @tab-click="tabClick"
    5. :before-leave="confirmLeave"
    6. >
    7. ......

    ②写提示方法

    1. methods: {
    2. async confirmLeave(pane){
    3. if(pane!=='flimLibrary' && this.$store.state.router.isEditing){
    4. return await this.$confirm('您所做的更改暂未保存,确认离开页面??', '温馨提示', {
    5. confirmButtonText: '确定',
    6. cancelButtonText: '取消',
    7. type: 'warning'
    8. })
    9. .then(() => {
    10. this.$store.commit('router/SET_EDITING', false)
    11. this.$emit('update:actived', pane)
    12. this.isIgnore = true
    13. return true
    14. })
    15. .catch(() => {
    16. this.isIgnore = false
    17. return reject()
    18. })
    19. }
    20. }
    21. },

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

    三、 效果

    ①切换组件/跳转路由

    ②关闭标签页

    ③刷新页面

  • 相关阅读:
    Linux中的五种网络API的模型的解释
    JS高级:执行上下文
    基于51单片机的模拟心率电子脉搏器proteus仿真原理图PCB
    现代卷积神经网络 - 批量规范化
    2022最新Java面试宝典(史上最全,BAT大厂面试必备,用心看完该篇就够了,建议先关注点赞加收藏)
    【MySQL学习】常见命令
    使用Kubernetes中的Nginx来改善第三方服务的可靠性和延迟
    怎么用测量来分辨双向TVS管的好坏?-优恩
    Converting HTML to PDF in .NET 7 Crack
    给页面加一个灰度的滤镜
  • 原文地址:https://blog.csdn.net/Vivien_CC/article/details/139655722