前言
大家在开发后台管理系统的过程中,一定会遇到一个表格的条件查询重置功能吧,如果说查询条件少,重置起来还算是比较简单,如果元素特别多呢,那玩意写起来可遭老罪喽,那今天就给大家整一个如何快速重置数据的功能吧
实现方式一
实现方式一较为简单,就不上代码了,大概就是创建两个一样的数据,修改的是其中一个,然后需要重置的时候,将另一个定义的数据深拷贝给被修改的数据,就可以实现了
实现方式二
基本的思路跟实现方式一是一样的,只不过稍微处理了一下,封装成一个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-tag
v-for="(item, index) in scope.row.tags"
:key="index"
:type="tagType[index % tagType.length]"
>{{ item }}</el-tag
>
</template>
<template #isAppear="scope">
<el-select
v-model="scope.row.isAppear"
style="width: 120px"
@change="(value) => changeIsAppear(value, scope.row.id)"
>
<el-option
v-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-switch
v-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’)
总结
以上就是通过函数的方式实现数据重置,本质上还是通过一个新的数据对老数据进行覆盖,如果有问题欢迎提出