Vue:axios请求完成后如何正确填充编辑表单数据
Vue编辑表单开发问题解决方案
1. 表单赋值失效问题修复
失效的核心原因是:你的表单字段通过v-model绑定的是form对象下的属性,你直接给未在data中声明的this.name赋值,既不属于响应式变量,也和表单绑定对象无关,自然不会同步到视图。
正确赋值方式:
修改mounted钩子中的赋值逻辑即可,单字段赋值:
// 替换原来的 this.name = response.data.data.name this.form.name = response.data.data.name this.form.image = response.data.data.image
如果接口返回的字段和form对象中定义的字段完全对应,可以用批量赋值减少重复代码:
Object.assign(this.form, response.data.data)
同时补充加载态的初始化逻辑,请求发起前将storing设为true,避免刚进入页面加载时没有加载提示:
mounted() { // 先开启加载态 this.storing = true axios.get('/datas/' + this.$route.params.id).then(response => { Object.assign(this.form, response.data.data) }) .catch(err => { // 错误处理逻辑 }) .finally(() => { this.storing = false }) }
2. 同表单兼容新增/编辑场景实现
完全可以实现单表单同时支持新增和编辑,核心逻辑通过路由参数判断场景,动态切换请求逻辑和页面展示:
实现步骤:
- 新增编辑状态标识,在
data中添加isEdit: false变量,初始化时判断路由是否携带id参数,存在则为编辑场景 - 动态修改页面标题、提交按钮文字等展示内容,根据
isEdit状态区分 - 提交方法中根据状态切换请求方法和接口地址:新增调用
POST /datas,编辑调用PUT /datas/{id} - 编辑场景下额外增加已上传图片的回显逻辑,用户未上传新图片时直接复用原有路径提交
核心优化代码示例:
<template> <base-layout :layout-classes="layoutClasses"> <div class="container mt-3"> <div v-if="storing"> <h3>请稍候....</h3> </div> <div class="content"> <base-block rounded :title="isEdit ? '编辑数据' : '创建数据'"> <b-form @submit.prevent="submitForm" class="mb-5"> <b-form-group label-cols-sm="2" label="名称"> <b-form-input v-model="form.name" class="form-control-alt" type="text" placeholder="名称"></b-form-input> </b-form-group> <b-form-group label="图片" label-cols-sm="2"> <!-- 编辑场景回显已上传图片 --> <img v-if="isEdit && form.image" :src="form.image" class="mb-2" style="max-width: 200px"> <b-form-file plain v-on:change="onFileChange($event, 'image')"></b-form-file> </b-form-group> <b-form-group label="" label-cols-sm="2"> <b-button type="submit" class="text-white" variant="dark">{{ isEdit ? '保存修改' : '提交新增' }}</b-button> </b-form-group> </b-form> </base-block> </div> </div> </base-layout> </template> <script> import BaseLayout from '../layouts/Base/Base.vue' export default { data () { return { form: { name: '', image: null }, storing: false, isEdit: false, layoutClasses: { sideOverlay: true, sidebar: true, header: true, footer: true } } }, components: { BaseLayout }, methods: { onFileChange(e, key){ let formData = new FormData(); formData.append('file', e.target.files[0]); formData.append('dir', 'datas'); axios.post('/uploads', formData, { headers: { 'content-type': 'multipart/form-data' } }) .then(({data}) => { this.form[key] = data.data.path }) .catch(err => { Object.assign(this.errors, {}, err.response.data.errors) }) }, submitForm() { this.storing = true let request if (this.isEdit) { // 编辑场景调用更新接口 request = axios.put(`/datas/${this.$route.params.id}`, this.form) } else { // 新增场景调用创建接口 request = axios.post('/datas', this.form) } request.then(res => { // 提交成功后的跳转、提示逻辑 }).catch(err => { // 错误处理逻辑 }).finally(() => { this.storing = false }) } }, mounted() { // 判断是否为编辑场景 if (this.$route.params.id) { this.isEdit = true this.storing = true axios.get('/datas/' + this.$route.params.id).then(response => { Object.assign(this.form, response.data.data) }) .catch(err => { // 错误处理逻辑 }) .finally(() => { this.storing = false }) } } } </script>
内容的提问来源于stack exchange,提问作者Gaurav
相关产品推荐
相关产品推荐

