51 lines
1.3 KiB
Vue
51 lines
1.3 KiB
Vue
|
<script setup lang="ts">
|
||
|
import { ref } from "vue";
|
||
|
|
||
|
type optionalMap<Optional> = Optional extends true ? undefined : string | number;
|
||
|
// type typeMap<Type extends string = {};
|
||
|
|
||
|
export type fieldDefinition<Optional extends boolean = boolean> = {
|
||
|
key: string,
|
||
|
label?: string,
|
||
|
type: "text" | "number",
|
||
|
optional?: Optional,
|
||
|
value?: optionalMap<Optional>,
|
||
|
}
|
||
|
|
||
|
const props = defineProps<{
|
||
|
fields: Array<fieldDefinition>,
|
||
|
}>();
|
||
|
|
||
|
// eslint-disable-next-line func-call-spacing
|
||
|
const emit = defineEmits<{
|
||
|
(e: "update:modelValue", value: any): void,
|
||
|
(e: "updateSubModelValue", key: fieldDefinition["key"], value: fieldDefinition["value"]): void,
|
||
|
}>();
|
||
|
|
||
|
const modelValue = ref<{[key: string]: string | number | undefined}>({});
|
||
|
|
||
|
for (const i of props.fields) {
|
||
|
modelValue.value[i.key] = i.value;
|
||
|
emit("updateSubModelValue", i.key, i.value);
|
||
|
}
|
||
|
|
||
|
function updateModel(key: string, v: any) {
|
||
|
modelValue.value[key] = v;
|
||
|
emit("update:modelValue", modelValue.value);
|
||
|
emit("updateSubModelValue", key, v);
|
||
|
}
|
||
|
|
||
|
emit("update:modelValue", modelValue.value);
|
||
|
</script>
|
||
|
|
||
|
<template>
|
||
|
<VTextField
|
||
|
v-for="i of fields"
|
||
|
:key="i.key"
|
||
|
:model-value="modelValue[i.key]"
|
||
|
:label="i.label"
|
||
|
:type="i.type"
|
||
|
@update:model-value="v => updateModel(i.key, v)"
|
||
|
/>
|
||
|
</template>
|