refactor: ♻️ cURD表单字段支持watch监听
This commit is contained in:
@@ -14,8 +14,12 @@
|
|||||||
>
|
>
|
||||||
<template v-for="item in modalConfig.formItems" :key="item.prop">
|
<template v-for="item in modalConfig.formItems" :key="item.prop">
|
||||||
<el-form-item :label="item.label" :prop="item.prop">
|
<el-form-item :label="item.label" :prop="item.prop">
|
||||||
|
<!-- Input 输入框 -->
|
||||||
|
<template v-if="item.type === 'input'">
|
||||||
|
<el-input v-model="formData[item.prop]" v-bind="item.attrs" />
|
||||||
|
</template>
|
||||||
<!-- Select 选择器 -->
|
<!-- Select 选择器 -->
|
||||||
<template v-if="item.type === 'select'">
|
<template v-else-if="item.type === 'select'">
|
||||||
<el-select v-model="formData[item.prop]" v-bind="item.attrs">
|
<el-select v-model="formData[item.prop]" v-bind="item.attrs">
|
||||||
<template v-for="option in item.options" :key="option.value">
|
<template v-for="option in item.options" :key="option.value">
|
||||||
<el-option :label="option.label" :value="option.value" />
|
<el-option :label="option.label" :value="option.value" />
|
||||||
@@ -30,6 +34,13 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- Input Number 数字输入框 -->
|
||||||
|
<template v-else-if="item.type === 'input-number'">
|
||||||
|
<el-input-number
|
||||||
|
v-model="formData[item.prop]"
|
||||||
|
v-bind="item.attrs"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<!-- TreeSelect 树形选择 -->
|
<!-- TreeSelect 树形选择 -->
|
||||||
<template v-else-if="item.type === 'tree-select'">
|
<template v-else-if="item.type === 'tree-select'">
|
||||||
<el-tree-select v-model="formData[item.prop]" v-bind="item.attrs" />
|
<el-tree-select v-model="formData[item.prop]" v-bind="item.attrs" />
|
||||||
@@ -64,7 +75,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive } from "vue";
|
import { ref, reactive, watch } from "vue";
|
||||||
import { useThrottleFn } from "@vueuse/core";
|
import { useThrottleFn } from "@vueuse/core";
|
||||||
import type {
|
import type {
|
||||||
DialogProps,
|
DialogProps,
|
||||||
@@ -92,7 +103,14 @@ export interface IModalConfig<T = any> {
|
|||||||
// 表单项
|
// 表单项
|
||||||
formItems: Array<{
|
formItems: Array<{
|
||||||
// 组件类型(如input,select,radio,custom等,默认input)
|
// 组件类型(如input,select,radio,custom等,默认input)
|
||||||
type?: string;
|
type?:
|
||||||
|
| "input"
|
||||||
|
| "select"
|
||||||
|
| "radio"
|
||||||
|
| "tree-select"
|
||||||
|
| "date-picker"
|
||||||
|
| "input-number"
|
||||||
|
| "custom";
|
||||||
// 组件属性
|
// 组件属性
|
||||||
attrs?: IObject;
|
attrs?: IObject;
|
||||||
// 组件可选项(适用于select,radio组件)
|
// 组件可选项(适用于select,radio组件)
|
||||||
@@ -107,6 +125,8 @@ export interface IModalConfig<T = any> {
|
|||||||
rules?: FormItemRule[];
|
rules?: FormItemRule[];
|
||||||
// 初始值
|
// 初始值
|
||||||
initialValue?: any;
|
initialValue?: any;
|
||||||
|
// 监听函数
|
||||||
|
watch?: (newValue: any, oldValue: any, data: T) => void;
|
||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -125,13 +145,27 @@ const formRef = ref<InstanceType<typeof ElForm>>();
|
|||||||
const formData = reactive<IObject>({});
|
const formData = reactive<IObject>({});
|
||||||
const formRules: FormRules = {};
|
const formRules: FormRules = {};
|
||||||
// 初始化
|
// 初始化
|
||||||
|
for (const item of props.modalConfig.formItems) {
|
||||||
|
formData[item.prop] = item.initialValue ?? "";
|
||||||
|
formRules[item.prop] = item.rules ?? [];
|
||||||
|
if (item.watch !== undefined) {
|
||||||
|
watch(
|
||||||
|
() => formData[item.prop],
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
item.watch?.(newValue, oldValue, formData);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 显示dialog
|
||||||
function setModalVisible(initData: IObject = {}) {
|
function setModalVisible(initData: IObject = {}) {
|
||||||
dialogVisible.value = true;
|
dialogVisible.value = true;
|
||||||
for (const item of props.modalConfig.formItems) {
|
for (const key in formData) {
|
||||||
formData[item.prop] = initData[item.prop] ?? item.initialValue ?? "";
|
if (Object.hasOwn(formData, key) && key in initData) {
|
||||||
formRules[item.prop] = item.rules ?? [];
|
formData[key] = initData[key];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (initData[pk]) {
|
if (Object.hasOwn(initData, pk)) {
|
||||||
formData[pk] = initData[pk];
|
formData[pk] = initData[pk];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,16 @@
|
|||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<template v-for="item in searchConfig.formItems" :key="item.prop">
|
<template v-for="item in searchConfig.formItems" :key="item.prop">
|
||||||
<el-form-item :label="item.label" :prop="item.prop">
|
<el-form-item :label="item.label" :prop="item.prop">
|
||||||
|
<!-- Input 输入框 -->
|
||||||
|
<template v-if="item.type === 'input'">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams[item.prop]"
|
||||||
|
v-bind="item.attrs"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<!-- Select 选择器 -->
|
<!-- Select 选择器 -->
|
||||||
<template v-if="item.type === 'select'">
|
<template v-else-if="item.type === 'select'">
|
||||||
<el-select v-model="queryParams[item.prop]" v-bind="item.attrs">
|
<el-select v-model="queryParams[item.prop]" v-bind="item.attrs">
|
||||||
<template v-for="option in item.options" :key="option.value">
|
<template v-for="option in item.options" :key="option.value">
|
||||||
<el-option :label="option.label" :value="option.value" />
|
<el-option :label="option.label" :value="option.value" />
|
||||||
@@ -58,7 +66,7 @@ export interface ISearchConfig {
|
|||||||
// 表单项
|
// 表单项
|
||||||
formItems: Array<{
|
formItems: Array<{
|
||||||
// 组件类型(如input,select等)
|
// 组件类型(如input,select等)
|
||||||
type: string;
|
type?: "input" | "select" | "tree-select" | "date-picker";
|
||||||
// 标签文本
|
// 标签文本
|
||||||
label: string;
|
label: string;
|
||||||
// 键名
|
// 键名
|
||||||
|
|||||||
Reference in New Issue
Block a user