关于前端创建添加和更新使用同一页面的问题

82 阅读2分钟

一.后端接口创建

//4 添加医院设置
@PostMapping("saveHospitalSet")
public Result saveHospitalSet(@RequestBody HospitalSet hospitalSet) {
    //设置状态 1 使用 0 不能使用
    hospitalSet.setStatus(1);
    //签名秘钥
    Random random = new Random();
    hospitalSet.setSignKey(MD5.encrypt(System.currentTimeMillis()+""+random.nextInt(1000)));
    //调用service
    boolean save = hospitalSetService.save(hospitalSet);
    if(save) {
        return Result.ok();
    } else {
        return Result.fail();
    }
}
//5 根据id获取医院设置
@GetMapping("getHospSet/{id}")
public Result getHospSet(@PathVariable Long id) {
    HospitalSet hospitalSet = hospitalSetService.getById(id);
    return Result.ok(hospitalSet);
}

//6 修改医院设置
@PostMapping("updateHospitalSet")
public Result updateHospitalSet(@RequestBody HospitalSet hospitalSet) {
    boolean flag = hospitalSetService.updateById(hospitalSet);
    if(flag) {
        return Result.ok();
    } else {
        return Result.fail();
    }
}

为什么要写一个根据id获得医院设置的方法呢?这是因为在前端添加和修改打算用同一个页面,但区别在于修改会获取对应数据的id,因此实体上会比添加多id值

二.前端对应接口

//添加 saveHospSet(hospSetObj){ return request({ url:/admin/hosp/hospitalSet/saveHospitalSet`, method: 'post', data:hospSetObj }) },

//医院设置id查询 getHospSet(id){ return request({ url: /admin/hosp/hospitalSet/getHospSet/${id}, method: 'get' }) },

//修改 updateHospSet(hospSetObj){ return request({ url: /admin/hosp/hospitalSet/updateHospitalSet, method: 'post', data:hospSetObj }) },`

method的类型和后端方法一致,如果后端传的是@RequestBody,说明传的是json对象,前端应对应data定义对象

然后在表单中定义按钮并附带点击事件

<el-form-item> <el-button type="primary" @click="saveOrUpdate">保存</el-button> </el-form-item>

在前端路由里定义隐藏路由

  {
    path: '/hospSet',
    component: Layout,
    redirect: '/hospSet/list',
    name: '医院设置管理',
    meta: { title: '医院设置管理', icon: 'example' },
    children: [
      {
        path: 'list',
        name: '医院设置列表',
        component: () => import('@/views/hospSet/list'),
        meta: { title: '医院设置列表', icon: 'table' }
      },
      {
        path: 'add',
        name: '医院设置添加',
        component: () => import('@/views/hospSet/add'),
        meta: { title: '医院设置添加', icon: 'tree' }
      },
      {
        path: 'edit/:id',
        name: 'EduTeacherEdit',
        component: () =>import('@/views/hospSet/add'),
        meta: { title: '编辑', noCache: true },
        hidden: true
        }
    ]
  },

其中编辑要传id值所以path后加:id代表路由中传了id

在列表显示页定义路由:

<router-link :to="'/hospSet/edit/'+scope.row.id">
                <el-button type="primary" size="mini" icon="el-icon-edit"></el-button>
              </router-link>

path对应先总路由hospSet然后在对应下面的子元素路由edit,并且scope.row.id传id值给编辑方法

在添加页添加修改添加等方法,因为都共用同一页面

 import hospset from "@/api/hospset";
export default {
  data() {
    return {
      hospitalSet: {}
    };
  },
  created() {
    //获取路由的隐藏id值
    if (this.$route.params && this.$route.params.id) {
      const id = this.$route.params.id;
      this.getHospSet(id);
    }
  },
  methods: {
    //修改
    update() {
      hospset.updateHospSet(this.hospitalSet).then(res => {
        this.$message({
          type: "success",
          message: "修改成功!"
        });
        this.$router.push({ path: "/hospSet/list" });
      });
    },
    //添加
    save() {
      hospset.saveHospSet(this.hospitalSet).then(res => {
        this.$message({
          type: "success",
          message: "添加成功!"
        });
        this.$router.push({ path: "/hospSet/list" });
      });
    },
    //根据id查询医院设置
    getHospSet(id) {
      hospset.getHospSet(id).then(res => {
        this.hospitalSet = res.data;
      });
    },
    saveOrUpdate() {
      //判断是修改还是添加
      if (this.hospitalSet.id) {
        this.update();
      } else {
        this.save();
      }
    }
  }
};

saveOrUpdate()方法中根据对象是否存在id值来判断调用哪个方法,并触发添加页的点击事件

三.bug

这样会存在一个bug,就是生命周期创造时只会渲染一次但是如果先点击修改跳到路由对应页再点击添加就不会渲染了,就是说编辑会带来对应id的数据,但再点击新增时数据理应清空url没id值,但现在id值没有但数据仍然保留了对应编辑id的数据

解决方式: 在APP-main里给路由添加一个key属性,这个属性是唯一值但会变化,用计算属性或者watch直接对路由进行监视,因为id值会变因此会生效,代码如下:

<template>
  <section class="app-main">
    <transition name="fade-transform" mode="out-in">
      <!-- or name="fade" -->
      <router-view :key="key"></router-view>
      <router-view/>
    </transition>
  </section>
</template>

<script>
export default {
  name: 'AppMain',
  computed: {
    key() {
      return this.$route.name !== undefined ? this.$route.name + +new Date() : this.$route + +new Date()
    }
  }
}
</script>

<style scoped>
.app-main {
  /*50 = navbar  */
  min-height: calc(100vh - 50px);
  position: relative;
  overflow: hidden;
}
</style>