表单页面未保存时不可跳转到其他页面

1,102 阅读1分钟

做一个表单页面提交内容时,会有用户输入表单内容未提交或者未保存就离开页面了,但是我们的业务需求在用户未保存或者未提交的情况下不给用户跳转页面或者弹出提示框。这时候可以用到组件内守卫beforeRouteLeave() 该守卫在导航离开渲染该组件的对应路由时调用。

下面看具体使用例子,以elementUI的表单组件为例,定义一个变量status判断当前表单是否保存/提交;在beforeRouteLeave内写入相应逻辑判断是否可跳转。

<template>
  <div class="app-container">
    <div>
      <el-form ref="form" :model="form" label-width="80px">
        <el-form-item label="新闻标题">
          <el-input v-model="form.title" style="width: 300px;"></el-input>
        </el-form-item>
        <el-form-item label="新闻类型">
          <el-radio-group v-model="form.type">
            <el-radio :label="1">新闻</el-radio>
            <el-radio :label="2">其他</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="新闻时间">
          <el-date-picker type="datetime" placeholder="选择时间" value-format="yyyy-MM-dd hh:mm:ss" v-model="form.news_time" style="width: 300px;"></el-date-picker>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">{{ btnText }}</el-button>
          <el-button>取消</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        form: {
          title: '',
          type: '',
          news_time: ''
        },
        btnText: '立即创建',
        status: false, //保存状态 false未保存
      }
    },
    methods: {
      onSubmit() {
        //TODO这里做表单提交或者保存处理
        this.status = true //已保存
      }
    },
    // 页面跳转之前判断当前表单页面是否保存提交
    beforeRouteLeave(to, from, next) {
      let form_status = false
      // 判断是否有填写入表单内容
      for(const key in this.form) {
        if(this.form[key]) {
         form_status = true //有写入内容
        }
      }
      //当前表单有填写内容且未提交时弹出弹框确认
      if (!this.status && form_status == true) {
        this.$confirm("您填写的内容未保存,确定离开吗?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(() => {
          next();
        }).catch(() => {});
      } else {
        next();
      }
    }
  }
</script>