- 新增 FieldObject.vue(嵌套字段组,display/edit 递归渲染)、FieldArray.vue (元素列表,增删 + 每项递归渲染 item;第一版从简:无排序拖拽)。靠 glob 自动注册成 object/array。 - 删 FieldJson.vue(json 类型退场,object 取代)。 - 版本与 shrimp-server 统一为 0.7.0。
70 lines
2.0 KiB
Vue
70 lines
2.0 KiB
Vue
<template>
|
||
<!-- 显示:递归渲染各子字段的 display 组件(relation 子查 refs) -->
|
||
<template v-if="mode === 'display'">
|
||
<span v-if="!modelValue || typeof modelValue !== 'object'">-</span>
|
||
<span v-else class="obj-display">
|
||
<span v-for="f in field.fields || []" :key="f.key" class="obj-child">
|
||
<span class="obj-label">{{ vueAdmin.t(f.label) }}:</span>
|
||
<component :is="vueAdmin.getFieldComponent(moduleKey, f.type, f.key)"
|
||
:field="f" :model-value="(modelValue || {})[f.key]" mode="display" />
|
||
</span>
|
||
</span>
|
||
</template>
|
||
<!-- 编辑:每个子字段一行,递归渲染 edit 组件 -->
|
||
<div v-else class="field-object">
|
||
<el-form-item v-for="f in field.fields || []" :key="f.key" :label="vueAdmin.t(f.label)" :required="f.required">
|
||
<component :is="vueAdmin.getFieldComponent(moduleKey, f.type, f.key)"
|
||
:field="f" :model-value="(modelValue || {})[f.key]"
|
||
@update:model-value="onChild(f.key, $event)" mode="edit" :disabled="disabled" />
|
||
</el-form-item>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { inject } from 'vue'
|
||
import { vueAdmin } from '../../VueAdmin'
|
||
|
||
const props = defineProps<{
|
||
field: any
|
||
modelValue: any
|
||
mode: 'display' | 'edit' | 'filter'
|
||
disabled?: boolean
|
||
}>()
|
||
|
||
const emit = defineEmits<{ 'update:modelValue': [value: any] }>()
|
||
|
||
const moduleKey = inject('shrimpModuleKey', '')
|
||
|
||
function onChild(key: string, value: any) {
|
||
emit('update:modelValue', { ...(props.modelValue || {}), [key]: value })
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.obj-display {
|
||
display: inline-flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: 4px 10px;
|
||
}
|
||
|
||
.obj-child {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
.obj-label {
|
||
color: var(--el-text-color-secondary);
|
||
font-size: 12px;
|
||
}
|
||
|
||
.field-object {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
padding-left: 12px;
|
||
border-left: 2px solid var(--el-border-color-lighter);
|
||
}
|
||
</style>
|