前言
大家在开发后台管理系统的过程中,一定会遇到一个表格的条件查询重置功能吧,如果说查询条件少,重置起来还算是比较简单,如果元素特别多呢,那玩意写起来可遭老罪喽,那今天就给大家整一个如何快速重置数据的功能吧
实现方式一
实现方式一较为简单,就不上代码了,大概就是创建两个一样的数据,修改的是其中一个,然后需要重置的时候,将另一个定义的数据深拷贝给被修改的数据,就可以实现了
实现方式二
基本的思路跟实现方式一是一样的,只不过稍微处理了一下,封装成一个hooks,这样只需要自定义数据的时候执行这个函数即可; 上代码
import { reactive, isRef } from 'vue';// 深拷贝函数,避免使用 JSON.parse(JSON.stringify) 的局限性
const deepClone = (obj: any) => {return JSON.parse(JSON.stringify(obj));// 或者使用更健壮的实现,比如 lodash 的 cloneDeep// return _.cloneDeep(obj);
};export const useReset = <T extends object>(value: T) => {// 如果 value 是 ref,则获取其值const state = isRef(value)? reactive(deepClone(value.value)): reactive(deepClone(value));const reset = (key?: keyof T, specificResetValue?: any) => {// 如果指定了 key,重置该属性if (key) {if (specificResetValue !== undefined) {// 如果提供了 specificResetValue,重置为这个值state[key] = specificResetValue;} else if (key in value) {// 否则重置为初始值state[key] = deepClone((value as any)[key]);}} else {// 如果没有指定 key,重置为初始值Object.assign(state, deepClone(value));}// 删除 state 中不再存在于 value 的属性Object.keys(state).forEach((k) => {if (!(k in value)) {delete state[k];}});};return { state, reset };
};
注意:深拷贝建议使用已经lodash或者其他比较完善的深拷贝方法,这里只是简单处理,知道原理即可
使用方式:
<el-button @click="reset('form')">重置</el-button>
const { state, reset } = useReset({form: { title: '', typeId: '', type: '', isAppear: '' },formList: [{type: 'input',label: '标题',value: 'title',attrs: {placeholder: '请输入标题',width: '120',},// formLabel: '标题',formItemAttrs: {prop: 'title',label: '标题',labelWidth: '50px',},},{type: 'select',label: '分类',value: 'typeId',attrs: {placeholder: '请输入分类',width: '120',style: 'width: 120px',},formItemAttrs: {prop: 'typeId',label: '分类',},selectlabel: 'type',Keyvalue: 'id',list: [],childrenComponent: {type: 'option',},},{type: 'select',label: '类型',value: 'type',attrs: {placeholder: '请选择类型',width: '120',style: 'width: 120px',},formItemAttrs: {prop: 'type',label: '类型',},selectlabel: 'label',Keyvalue: 'value',list: [{ value: 1, label: '原创' },{ value: 2, label: '转载' },],childrenComponent: {type: 'option',},},{type: 'select',label: '状态',value: 'isAppear',attrs: {placeholder: '请选择状态',width: '120',style: 'width: 120px',},formItemAttrs: {prop: 'type',label: '状态',},selectlabel: 'label',Keyvalue: 'value',list: [{ value: 1, label: '可见' },{ value: 3, label: '草稿' },],childrenComponent: {type: 'option',},},],
});
上面的实现可以只对某一个属性进行重置,案例
<template><div style="height: 100vh"><kt-form v-model="state" :formAttrs="formAttrs"></kt-form><el-button @click="see" type="primary">查询</el-button><el-button @click="reset('form')">重置</el-button><!-- <el-button type="primary" @click="add">添加</el-button> --><kt-table:column="articleColumn":default-sort="{ prop: 'date', order: 'descending' }":tableData@selection-change="handleSelectionChange":page-sizes="[10, 20, 30, 40]"layout="total, sizes, prev, pager, next, jumper"v-model="page":total:tableColumnAttrs="tableColumnAttrs"@confirm="confirm"@handleClick="handleClick"><template #tags="scope"><el-tagv-for="(item, index) in scope.row.tags":key="index":type="tagType[index % tagType.length]">{{ item }}</el-tag></template><template #isAppear="scope"><el-selectv-model="scope.row.isAppear"style="width: 120px"@change="(value) => changeIsAppear(value, scope.row.id)"><el-optionv-for="item in isAppearList":key="item.value":label="item.label":value="item.value"></el-option></el-select></template><template #type="scope"><el-tag :type="appear(scope.row.type)">{{ scope.row.type === '1' ? '原创' : '转载' }}</el-tag></template><template #isTop="scope"><el-switchv-model="scope.row.isTop"active-value="1"inactive-value="2"@change="(value) => changeIsAppear(value, scope.row.id)"/></template><template #typeId="scope">{{ format(scope.row.typeId) }}</template></kt-table>{{ state.id }}</div>
</template>
<script setup lang="ts">
import { articleColumn } from '@/common/column';
import { list, update, del } from '@/request/article';
import { useReset } from '@/hooks/useResert';
import { ElMessage } from 'element-plus';
import { useTypelist } from '@/hooks/useTypelist';
import router from '@/router';
import { useInit } from '@/store/index.ts';
const init = useInit();
const typeList = ref<any[]>([]);import 'element-plus/theme-chalk/el-message.css';
const formAttrs = {inline: true,labelWidth: '50px',
};interface IArticle {id: number;[key: string]: any;
}
let total = 0;
const { state, reset } = useReset({form: { title: '', typeId: '', type: '', isAppear: '' },formList: [{type: 'input',label: '标题',value: 'title',attrs: {placeholder: '请输入标题',width: '120',},// formLabel: '标题',formItemAttrs: {prop: 'title',label: '标题',labelWidth: '50px',},},{type: 'select',label: '分类',value: 'typeId',attrs: {placeholder: '请输入分类',width: '120',style: 'width: 120px',},formItemAttrs: {prop: 'typeId',label: '分类',},selectlabel: 'type',Keyvalue: 'id',list: [],childrenComponent: {type: 'option',},},{type: 'select',label: '类型',value: 'type',attrs: {placeholder: '请选择类型',width: '120',style: 'width: 120px',},formItemAttrs: {prop: 'type',label: '类型',},selectlabel: 'label',Keyvalue: 'value',list: [{ value: 1, label: '原创' },{ value: 2, label: '转载' },],childrenComponent: {type: 'option',},},{type: 'select',label: '状态',value: 'isAppear',attrs: {placeholder: '请选择状态',width: '120',style: 'width: 120px',},formItemAttrs: {prop: 'type',label: '状态',},selectlabel: 'label',Keyvalue: 'value',list: [{ value: 1, label: '可见' },{ value: 3, label: '草稿' },],childrenComponent: {type: 'option',},},],
});const tagType: any = ['primary', 'success', 'info', 'warning', 'danger'];
const see = () => {// console.log(forms.form);// reset(state.form);console.log(state);getList();
};
const tableColumnAttrs = {fixed: 'right',align: 'center',minWidth: '120',
};const tableData = ref([]);
const page = ref({currentPage: 1,currentSize: 10,
});const handleSelectionChange = (val: any) => {console.log(val);
};const isAppearList = [{value: '1',label: '可见',},{value: '3',label: '草稿',},
];
const format = (id: string | number) => {// console.log(typeList, 'typeList');return typeList.value.find((item: any) => item.id === id)?.type || '';
};
const updateTable = async (id: number) => {const result: any = tableData.value.find((item: IArticle) => item.id === id);if (!result) return;const index: number = tableData.value.findIndex((item: IArticle) => item.id === id);const json: any = { ...result };json.tags = json.tags.join(',');// 调用更新const res = await update(json);if (res.status) {ElMessage.success(res.message);histList[index] = tableData.value[index] as IArticle;} else {ElMessage.error(res.message);// 还原原来的数据if (index !== -1) {(tableData.value[index] as IArticle) = histList[index];}}
};
// isAppear
// 切换状态
const changeIsAppear = async (_val: string | number | boolean, id: number) => {await updateTable(id);
};
const appear = (isAppear: string) => {switch (isAppear) {case '1':return tagType[1];case '2':return tagType[0];case '3':return tagType[3];default:return tagType[3];}
};
let histList: IArticle[] = [];
const getList = async () => {const json: any = { ...page.value, ...state.form };json.page = page.value.currentPage;json.pageSize = page.value.currentSize;const res = await list({ ...json });res.data.articles.forEach((item: any) => {item.tags = item.tags.split(',');});tableData.value = res.data.articles;total = res.data.totalCount;histList = JSON.parse(JSON.stringify(res.data.articles));
};// 删除单个
const confirm = async (row: IArticle) => {const res: any = await del(row.id);if (res.status) {ElMessage.success(res.message);getList();} else {ElMessage.error(res.message);}
};
// 编辑
const handleClick = (row: IArticle) => {init.changeCurrentTab('articleAdd', '1-2');// query传参跳转router.push({path: '/articleAdd',query: {id: row.id,},});
};
watch([() => page.value.currentPage, () => page.value.currentSize],() => {getList();},{ immediate: true },
);
onMounted(async () => {const { data } = await useTypelist();typeList.value = data.value;state.formList[1].list = data.value;
});
// 查询列表
</script>
<style lang="scss" scoped></style>
上面是一个页面,展示
其中,分类,类型和状态的下拉数据通过接口获取的,所以,当数据重置的时候,我是不能formList里面的数据,否则会导致下拉列表为空,这时候,只需要调用reset,然后传入需要重置的的数据,这里需要重置的是form,所以重置调用reset(‘form’)
总结
以上就是通过函数的方式实现数据重置,本质上还是通过一个新的数据对老数据进行覆盖,如果有问题欢迎提出