基于vue3.0和element-plus的组件库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

170 lines
4.5 KiB

<template>
<div class="modify-form">
<el-form
label-position="right"
:class="class"
:label-width="width ? width + 'px' : ''"
:model="param"
ref="modifyForm"
:rules="rules"
>
<template v-for="item in items">
<el-form-item :label="item.name || t(item.i18n)" :prop="item.code" v-if="!modify || (modify && !item.noModify)">
<template v-if="item.dict || item.maxValue">
<NoobSelect
v-if="!item.readonly"
v-model="param[item.code]"
:dict="item.dict"
:max-value="item.maxValue"
full
:placeholder="t('rule.pleaseSelect') + (item.name || t(item.i18n))"
:disabled="item.disabled"
/>
<el-input v-else readonly :model-value="sysDict[item.dict as string][param[item.code]]" />
</template>
<template v-else-if="item.date">
<NoobDate
v-if="!item.readonly"
v-model="param[item.code]"
:formater="item.formater"
full
:placeholder="t('rule.pleaseSelect') + (item.name || t(item.i18n))"
:disabled="item.disabled || item.readonly"
/>
<TzDateTime
v-else
:value="param[item.code]"
:value-format="item.formater"
display-format="YYYY-MM-DD HH:mm:ss"
slot
>
<template #default="{ display }">
<el-input :model-value="display" readonly />
</template>
</TzDateTime>
<!-- <span>{{ param[item.code].toString() }}</span>-->
</template>
<slot v-else-if="item.slot" :name="item.code" />
<NoobInput
v-else
v-model="param[item.code]"
full
:type="item.type"
:rows="item.rows"
:placeholder="item.readonly || item.disabled ? '空' : t('rule.pleaseEnter') + (item.name || t(item.i18n))"
:disabled="item.disabled"
:readonly="item.readonly"
/>
</el-form-item>
</template>
<slot></slot>
<el-form-item class="form-btns">
<NoobButton v-if="confirm || confirm === undefined" type="primary" @click="formConfirm">{{
t(typeof confirm === "string" && confirm ? confirm : "base.confirm")
}}</NoobButton>
<NoobButton v-if="cancel || cancel === undefined" type="info" @click="emit('cancel')">{{
t(typeof cancel === "string" && cancel ? cancel : "base.cancel")
}}</NoobButton>
</el-form-item>
</el-form>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref, watch } from "vue";
import { FormInstance } from "element-plus";
import { useI18n } from "vue3-i18n";
import { NoobSelect, NoobInput, NoobDate, NoobButton, TzDateTime, useSysDict } from "noob-mengyxu";
const { t } = useI18n();
const { sysDict, updateDict } = useSysDict();
interface FormItem {
code: string;
name?: string;
i18n?: string;
dict?: string;
maxValue?: number;
date?: boolean;
formater?: string;
slot?: boolean;
type?: string;
rows?: number;
disabled?: boolean;
noModify?: boolean;
readonly?: boolean;
}
interface Props {
width?: number;
param?: Record<string, any>;
rules?: Record<string, any>;
class?: string;
type?: string | null;
modify?: boolean;
items?: FormItem[];
confirm?: string | boolean | null;
cancel?: string | boolean | null;
}
const prop = withDefaults(defineProps<Props>(), {
width: 80,
param: () => ({}),
rules: () => ({}),
class: "",
type: null,
modify: false,
items: () => [],
confirm: undefined,
cancel: undefined,
});
const emit = defineEmits<{
confirm: [];
cancel: [];
}>();
const modifyForm = ref<FormInstance>();
const formConfirm = () => {
if (!modifyForm.value) return;
modifyForm.value?.validate((valid, fields) => {
if (valid) {
emit("confirm");
modifyForm.value?.clearValidate();
}
});
};
const clearValidate = () => {
modifyForm.value?.clearValidate();
};
watch(
() => prop.param,
() => {
modifyForm.value?.clearValidate();
}
);
defineExpose({ clearValidate });
onMounted(async () => {
await updateDict(prop.items.map((item) => item.dict).filter(Boolean) as string[]);
});
</script>
<style lang="scss" scoped>
//@import url(); 引入公共css类
:deep(.el-select) {
width: 100%;
}
:deep(.el-date-editor) {
width: 100% !important;
}
:deep(.el-autocomplete) {
width: 100%;
}
</style>