ts+vue3 elementUI表单提交编辑
需求:因为有些有唯一性校验的字段,如果没被编辑并且传了;后端更新时会失败;所以只传需要变更的字段。在提交表单使用http的put请求进行数据更新时,只提交表单中被修改的数据,而不是提交整个表单分析:获取表单数据时clone一份作为原始数据rawData在提交表单前将表单数据 formData 和 rawData 的数据进行比较将差异存放到新的对象 diffData 中,在提交表单时提交就行了<
·
需求:
因为有些有唯一性校验的字段,如果没被编辑并且传了;后端更新时会失败;所以只传需要变更的字段。
在提交表单使用http的put请求进行数据更新时,只提交表单中被修改的数据,而不是提交整个表单
分析:
获取表单数据时clone一份作为原始数据rawData
在提交表单前将表单数据 formData 和 rawData 的数据进行比较
将差异存放到新的对象 diffData 中,在提交表单时提交就行了
`Object.getOwnPropertyNames()`
Object.getOwnPropertyNames(rData).forEach((val: string, idx: number) => {
JSON.parse(JSON.stringify(row));
Reflect.ownKeys(JSON.parse(JSON.stringify(row)));
<!-- 编辑模态框 -->
<el-dialog
title="社区信息"
v-model="dialogEditVisible"
width="540px"
:before-close="handleClose">
<!-- <span>这是一段信息</span> -->
<el-form
:model="data.rowObject"
ref="dataForm"
label-position="left"
label-width="90px"
style="width: 400px; margin-left:50px;"
>
<div class="demo-input-suffix">
<el-row style="margin-top: 0px">
<el-col :span="5" :offset="1" style="text-align: center;height: 32px;line-height: 32px;color:#000;">
<span style="color:red;">*</span>社区名称
</el-col>
<el-col :span="14" :offset="0">
<el-input
placeholder="请输入内容"
v-model="data.rowObject.name"
size="small">
</el-input>
</el-col>
</el-row>
<el-row style="margin-top: 20px">
<el-col :span="5" :offset="1" style="text-align: center;height: 32px;line-height: 32px;color:#000;">
关联APP-ID
</el-col>
<el-col :span="14" :offset="0">
<el-input
placeholder="请输入内容"
v-model="data.rowObject.relateAppId"
:disabled="true"
size="small">
</el-input>
</el-col>
</el-row>
<el-row style="margin-top: 20px">
<el-col :span="5" :offset="1" style="text-align: center;height: 32px;line-height: 32px;color:#000;">
<span style="color:red;">*</span>社区ICON
</el-col>
<el-col :span="14" :offset="0">
<el-button size="small" @click="clickAppId(data.rowObject.relateAppId)">通过APP-ID拉取</el-button>
<!-- <el-button size="medium" @click="mupload">上传</el-button> -->
<el-upload
class="upload-demo"
:ref="myUpload"
action="https://jsonplaceholder.typicode.com/posts/"
accept="image/jpeg,image/png,image/jpg"
:on-change="handleChangePic"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-error="handleErrorPic"
:file-list="fileList"
list-type="picture"
:limit="1"
:on-exceed="handleExceed">
<el-button size="small" type="primary" :disabled="data.disableUploadFlag">点击上传</el-button>
<template #tip>
<div class="el-upload__tip">
只能上传 jpg/png/jepg 文件,且不超过 300kb
</div>
</template>
</el-upload>
</el-col>
</el-row>
<el-row style="margin-top: 20px">
<el-col :span="5" :offset="1" style="text-align: center;height: 32px;line-height: 32px;color:#000;">
社区基数
</el-col>
<el-col :span="14" :offset="0" class="sq_jishu">
<div class="sq_js_div">
<el-col :span="10" :offset="2" style="margin-top:5px">
基础用户量
</el-col>
<el-col :span="10" :offset="1">
<el-input
placeholder="请输入内容"
v-model="data.rowObject.baseUserNum"
size="small">
</el-input>
</el-col>
</div>
<div class="sq_js_div">
<el-col :span="10" :offset="3" style="margin-top: 5px;margin-right: 4px!important;">
基础热度
</el-col>
<el-col :span="10" :offset="1">
<el-input
placeholder="请输入内容"
v-model="data.rowObject.baseHotNum"
size="small">
</el-input>
</el-col>
</div>
</el-col>
</el-row>
<el-row style="margin-top: 20px">
<el-col :span="9" :offset="0"
style="text-align: center;height: 32px;line-height: 32px;color:#000;margin-left: -49px;">
<span style="color:red;">*</span>非管理员用户关联
</el-col>
<el-col :span="12" :offset="0">
<!-- <el-button type="" icon="el-icon-plus" size="small">添加</el-button> -->
<el-button type="" @click="innerVisible = true" size="small">添加</el-button>
</el-col>
<el-col :span="14" :offset="6" class="sq_jishu" style="margin-top:10px">
<div class="sq_jishu_div">
<div class="sq_jishu_div_role">
厂商
</div>
<div class="sq_jishu_div_tagAll">
<!-- <el-tag>标签一标签一</el-tag>
<el-tag>标签一标签一</el-tag> -->
<el-tag
:key="tag"
v-for="tag in dynamicTags"
closable
:disable-transitions="false"
@close="handleTagClose(tag)">
{{tag}}
</el-tag>
<el-tag
v-if="tagAddVisible"
closable
v-model="inputUserValue"
:disable-transitions="false"
@close="handleTagClose(tag)">
{{data.tag1}}
</el-tag>
</div>
</div>
</el-col>
</el-row>
</div>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogEditVisible = false">取 消</el-button>
<!-- <el-button type="primary" @click="dialogEditVisible = false">确 定</el-button> -->
<el-button type="primary" @click="clickEdit">确 定</el-button>
</span>
</template>
</el-dialog>
<script lang="ts">
import { defineComponent, reactive, ref, toRefs, onMounted, watchEffect, nextTick } from 'vue';
import { getCommunitTable, deleteTableDataApi, getAppIdApi, changeStatusApi, getCommunitSearchList, editCommunitApi } from '../../reactivity/getCommunityData';
import { ElMessage } from 'element-plus';
import { AnyObject } from 'element-plus/lib/el-table/src/table.type';
export default defineComponent({
setup() {
// const { pageInfo, tableList } = getCommunitTable({
// currentPage: data.pageInfo.currentPage, pageSize: data.pageInfo.pageSize });
// 定义翻页-初始化
const pageInfoInit = reactive({
currentPage: 1,
pageSize: 5,
});
const { pageInfo, tableList } = getCommunitTable({ ...pageInfoInit });
console.log('aaaaaaaaaaaaaaaaaaaaa', pageInfo);
console.log('bbbbbbbbbbbbbbbbbbbbb', tableList);
// const collapse = ref(false);
const tagsList = reactive([]);
const data = reactive({
pageInfo,
tableList,
value1: '',
options: [ // 下拉框选项内容
{
value: '选项1',
label: '上线中',
},
{
value: '选项2',
label: '下线中',
},
],
value: '', // 下拉框
activeNames: ['1'],
userRole: true, // false
isZhankai: true,
currentPage2: 1,
dialogEditVisible: false, // 编辑dialog展示
editInputcId: '',
rowObject: {}, // 模拟一个row一行数据信息 编辑模态框绑定数据
rawData: {}, // 获取表单时clone的原始数据————编辑copy
objT: { a: 1, b: 2, c: 3 },
diffData: {}, // 差异——编辑提交的内容
CommunityID: '', // 搜索id
searchInfo: { // 搜索里所有可填的信息
CommunityID: '', // 搜索条件ID
CommunityName: '', // 搜索条件昵称
communityTime: [], // [], // 搜索 创建时间到结束时间
connectUserQQ: '', // 搜索关联用户qq
cState: '', // 搜索 上线下线状态
},
delRowId: 0, // 查找到要删除的一行的id
delIndex: 0, // 当前一行要删除的索引index
// upOrDownRowId: 0, // 查找到要操作上下线的一行的id
upOrDownRowStatus: 0, // 操作上下线 + 删除操作 ——————————1-下线,2-上线,3-删除
dialogDelVisible: false, // 删除模态框初始化隐藏
editForm: { // 编辑模态框 -数据来源于一行的数据 ---暂时不使用
CommunityID: '', // 搜索条件ID
// 关联APP-ID 暂时空缺
CommunityName: '', // 搜索条件昵称
CommunityIcon: '', // 社区icon可以上传,可以通过关联appid 获取
editTime: '', // 编辑操作时间需要 前台记录当时时间
connectUserQQ: '', // 搜索关联用户qq ------非管理员用户关联 (可删除)
value: '', // 搜索 上线下线状态
// 关联用户 模态框还需要补充的内容 ----- 内嵌表格
userRole: '', // 用户类型
fileList: [{
name: '1.jpg',
url: 'files/1.jpg',
}, {
name: 'food2.jpeg',
url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
}],
// fileList: ['https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'],
// my_upload: ref(null), // 上传绑定----便于清除
},
dialogUpOrDownVisible: false, // 操作状态----模态框初始化隐藏
innerVisible: false, // 内嵌 添加社区的关联用户
form: { // 内嵌 添加社区的关联用户 表单信息
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: '',
},
formLabelWidth: '80px',
dialogAddVisible: false, // 创建社区模态框
gridData: [{
id: '123456',
name: '王小虎',
role: '版主',
}, {
id: '456123',
name: '王小',
role: '厂商',
}, {
id: '145623',
name: '小王',
role: '厂商',
}, {
id: '123456',
name: '小虎',
role: '写手',
}, {
id: '456123',
name: '王小',
role: '厂商',
}],
dynamicTags: ['标签一', '标签二', '标签三'], // 模拟添加关联社区 -- 用户标签
inputUserValue: '', // 输入的modle
disableUploadFlag: false, // 上传按钮是否置灰
addUser: { // 创建用户表单信息
id: 0,
name: '',
relateAppId: 0,
icon: '',
baseUserNum: 0,
baseHotNum: 0,
backgroundImg: '',
relateUser: '',
status: 0,
creatorId: 0,
createTime: 0,
operateTime: 0,
operatorId: 0,
iconSource: 0,
url: '', // 数据库 社区链接
createTimestamp: 0, // 创建时间
operateTimestamp: 0, // 更新 时间
},
tagAddVisible: false, // 动态添加关联tag
tag1: '', // 内模态框点击按钮- 获取的用户名称添加到社区信息中:非管理员用户关联tag里
});
const refData = toRefs(data);
console.log('refData:', refData);
const handleChange = () => {
data.isZhankai = !data.isZhankai;
// console.log('val', val);
// console.log('data.isZhankai:', data.isZhankai);
};
const handleEdit = (index: number, row: unknown) => {
console.log('当前索引index:', index, '当前行数row:', row);
data.dialogEditVisible = true;
// data.rowObject = row;
data.rowObject = JSON.parse(JSON.stringify(row)); // 解决element-ui中,在表单中修改数据,表格的数据也跟着修改的问题
// data.rawData = Reflect.ownKeys(JSON.parse(JSON.stringify(row))); // 编辑copy数据
data.rawData = JSON.parse(JSON.stringify(row));
console.log('data.rowObject:', data.rowObject, 'data.rawData:', data.rawData);
// console.log('data.rowObject:', Object.keys(data.rowObject), 'data.rawData:', Object.keys(data.rawData));
};
// 比较编辑差异的方法
const diffFormData = () => {
const rData: AnyObject = data.rawData;
const dData: AnyObject = data.diffData;
const formO: AnyObject = data.rowObject;
console.log('rData:', rData); // copy数据
Object.getOwnPropertyNames(rData).forEach((val: string, idx: number) => {
console.log(`${val} -> ${rData[val]}`);
console.log('idx:', idx);
if (rData[val] !== formO[val]) {
if (!data.diffData) { // 未修改
data.diffData = {};
}
dData[val] = formO[val];
console.log('dData[val]:', dData[val]);
}
console.log('dData:', dData);
});
editCommunitApi({ ...dData })
.then((res) => {
console.log('res:', res);
if (res && !res.ret) {
ElMessage.success({
message: '编辑成功成功',
type: 'success',
});
fetchData(data.pageInfo.pageNum, data.pageInfo.pageSize);
}
})
.finally(() => {
data.dialogEditVisible = false;
// return true;
});
};
// edit模态框提交修改内容 按钮
const clickEdit = () => {
diffFormData();
data.dialogEditVisible = false;
console.log('data.rowObject:', data.rowObject);
};
const handleDelete = (index: number, row: { id: number; status: number;}) => { // 删除模态框展示
console.log(index, row);
data.delRowId = row.id;
data.delIndex = index;
data.upOrDownRowStatus = 3;
console.log('data.delRowId:', data.delRowId, 'data.upOrDownRowStatus:', data.upOrDownRowStatus);
data.dialogDelVisible = true;
};
const fetchData = async (pageN: number|unknown, pageS: number|unknown) => { // 分页请求
// getCommunitTable({ pageNum: pageN, pageSize: pageS });
getCommunitSearchList({ pageNum: pageN, pageSize: pageS })
.then((res) => {
console.log('res:', res);
});
};
// 编辑 上传upload图片 --- 手动删除
const handleRemove = (file: { raw: { type: string; size: number; }; }, fileList: unknown) => {
console.log(file, fileList);
};
// 编辑 上传upload图片 点击上传按钮
const handlePreview = (file: unknown) => {
console.log('file:', file);
// handleChangePic(file, FileList);
};
// 限制上传文件个数
const handleExceed = (file: unknown, fileList: unknown) => {
console.log('file:', file, 'fileList:', fileList);
// this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
ElMessage.warning({
message: '当前限制选择 1 个图片文件文件',
type: 'warning',
duration: 2000,
});
};
// 限制上传文件格式为图片资源
const handleChangePic = (file: { raw: { type: string; size: number; }; }, fileList: unknown) => {
console.log('file:', file, 'fileList:', fileList);
const isTypeTrue = /^image\/(jpeg|png|jpg)$/.test(file.raw.type);
// console.log('this.refs', this.refs);
// eslint-disable-next-line no-mixed-spaces-and-tabs
const isLt300K = file.raw.size / 1024 < 300;
if (!isLt300K) {
ElMessage.error({
message: '上传图片大小不能超过300K!',
type: 'error',
duration: 2000,
});
handleRemove(file, fileList);
// data.my_upload.clearFiles(); // 清除文件对象
// this.$refs.upload.clearFiles();
// nextTick((el) => {
// console.log('myUpload:', el);
// // console.log('myUpload.clearFiles:', el.clearFiles);
// const el1 = { ...el };
// console.log('el:', el1);
// el1.clearFiles();
// });
}
if (!isTypeTrue) {
ElMessage.error({
message: '上传图片格式不对',
type: 'error',
duration: 2000,
});
};
const clickAppId = (appid: number) => {
console.log('appid:', appid);
// handleChangePic()
getAppIdApi({ appId: appid })
.then((res) => {
console.log('res111111111111:', res);
if (res && !res.ret) {
ElMessage.success({
message: '拉取成功',
type: 'success',
});
data.disableUploadFlag = true; // 上传按钮置灰
}
})
.finally(() => {
data.dialogDelVisible = false;
// return true;
});
};
// 文件上传失败出发的钩子 类型function(err, file, fileList)
const handleErrorPic = (error: unknown, file: unknown, fileList: unknown) => {
console.log('error:', error, 'file:', file, 'fileList:', fileList);
};
// handleUpOrDown_ 操作上线-线下点击事件
const handleUpOrDown = (index: number, row: { id: number; status: number; }) => { // 操作上线模态框展示
console.log(index, row);
data.delRowId = row.id;
// eslint-disable-next-line eqeqeq
if (row.status == 1) { // 当前1为下线
data.upOrDownRowStatus = 2;
// eslint-disable-next-line eqeqeq
} else if (row.status == 2) { // 当前2为上线
data.upOrDownRowStatus = 1;
}
console.log('data.delRowId:', data.delRowId, 'data.upOrDownRowStatus:', data.upOrDownRowStatus);
data.dialogUpOrDownVisible = true;
};
onMounted(() => {
// fetchData(data.pageInfo.pageSize);
watchEffect(() => {
// fetchData(data.pageInfo.pageSize);
});
handlesearch();
});
return {
...refData, tagsList,
pageInfo,
data,
handleEdit, // 编辑
handleRemove, // 编辑------上传图片 X取消按钮
handlePreview, // 编辑------上传upload图片 点击上传按钮
handleExceed, // 限制上传文件个数
handleChangePic, // 限制上传文件格式为图片资源
handleErrorPic, //
myUpload,
diffFormData, // 比较差异的方法
clickEdit, // 编辑模态框 确认按钮
clickAppId, // appid拉取的图片
fetchData, // 刷新查询数据信息
};
},
methods: {
},
});
</script>
展示效果:
修改部分内容之后:
点击【确定】按钮提交表单,
改变的信息:
只提交了修改的表单信息
import { request } from '@/services';
import { onMounted, Ref, ref } from 'vue';
import { AxiosRequestConfig } from 'axios';
import { AnyObject } from 'element-plus/lib/el-table/src/table.type';
interface pageInfo{
// pageNum当前第几页 pageSize每页记录数 total列表总条数 totalPage列表总页数
pageNum?: number
// currentPage?: number
pageSize?: number
total?: number
totalPage?: number
}
interface tableItem{
cId?: number
cName?: string
cTime?: string
cIcon?: string
cStatus?: boolean
cBuilder?: string
connectUser?: string
operator?: string
operatorTime?: string
}
// 添加用户列表信息
interface userItem{
userId?: number
nickName?: string
roleId?: number // 检索条件3(非必填):用户类型 2-厂商 3-版主 4-写手
}
interface communitInterface {
pageInfo?: pageInfo
// tableList?: Array<tableItem>
communities?: Array<tableItem>
}
interface userInterface {
pageInfo?: pageInfo
// tableList?: Array<tableItem>
users?: Array<userItem>
}
interface resultInterface<T> {
ret: number;
msg: string;
data: T;
}
// 获取社区列表
export function getCommunitTable(req: AnyObject): { pageInfo: Ref<pageInfo>, tableList: Ref<Array<tableItem>> } {
const pi = ref<pageInfo>({});
const ti = ref<Array<tableItem>>([]);
onMounted(async () => {
const { data } = await request<AxiosRequestConfig, resultInterface<communitInterface>>({
// url: '/api/community/get_community_list',
url: '/api/manage/community/batch',
method: 'get',
params: {
// pageNum: 10,
// pageSize: 5,
...req,
},
});
// pi.value = data?.data.pageInfo || {};
// ti.value = data?.data.tableList || [];
pi.value = data?.data.pageInfo || {};
ti.value = data?.data.communities || [];
console.log('communitytList data:', data);
});
return { pageInfo: pi, tableList: ti };
}
// 搜索
export function getCommunitSearchList(req: AnyObject): Promise<unknown> {
return request<AxiosRequestConfig, resultInterface<communitInterface>>({
url: '/api/manage/community/batch',
method: 'get',
params: {
...req,
},
});
}
// 删除
export function deleteTableDataApi(req: AnyObject): Promise<resultInterface<communitInterface> | AnyObject> {
return request<AxiosRequestConfig, resultInterface<communitInterface>>({
url: '/api/manage/community/status',
method: 'put',
params: {
...req,
},
});
}
// 通过appid拉取图片
interface appInfo{
appId?: number
appName?: string
icon?: string
}
interface appInfoInterface {
appInfo?: appInfo
}
// 通过appid拉取图片
export function getAppIdApi(req: AnyObject): Promise<resultInterface<appInfoInterface> | AnyObject> {
return request<AxiosRequestConfig, resultInterface<appInfoInterface>>({
url: '/api/manage/community/appinfo',
method: 'get',
params: {
...req,
},
});
}
// 社区状态变更 社区删除
// "status": number 社区状态:1-下线,2-上线,3-删除
export function changeStatusApi(req: AnyObject): Promise<resultInterface<communitInterface> | AnyObject> {
return request<AxiosRequestConfig, resultInterface<communitInterface>>({
url: '/api/manage/community/status',
method: 'put',
params: {
...req,
},
});
}
// 保存社区接口 ---社区创建、社区编辑
// id为0为创建,id!=0为社区编辑
// "iconSource": number 图标来源、用于前端显示:1-应用图标,2-上传
export function editCommunitApi(req: AnyObject): Promise<resultInterface<communitInterface> | AnyObject> {
return request<AxiosRequestConfig, resultInterface<communitInterface>>({
url: '/api/manage/community',
method: 'post',
params: {
...req,
},
});
}
// 查询单个社区信息
export function getOneCommunitApi(req: AnyObject): Promise<resultInterface<tableItem> | AnyObject> {
return request<AxiosRequestConfig, resultInterface<tableItem>>({
url: '/api/manage/community/',
method: 'get',
params: {
...req,
},
});
}
// 获取非管理员用户列表-过滤掉C端用户(可条件检索,条件空即检索所有非管理员用户) :创建社区-关联非管理员用户时用
export function getUserListApi(req: AnyObject): Promise<resultInterface<userInterface> | AnyObject> {
return request<AxiosRequestConfig, resultInterface<userInterface>>({
url: '/api/manage/user/query_non_administrator_list',
method: 'post',
params: {
...req,
},
});
}
更多推荐
已为社区贡献9条内容
所有评论(0)