85 lines
3.3 KiB
JavaScript
85 lines
3.3 KiB
JavaScript
window.ConfigSection = {
|
|
props: {
|
|
section: String,
|
|
label: String,
|
|
fields: Object,
|
|
modelValue: Object,
|
|
},
|
|
emits: ['update:modelValue'],
|
|
setup(props, { emit }) {
|
|
const { computed } = Vue;
|
|
|
|
const flatFields = computed(() => {
|
|
const result = [];
|
|
for (const [key, val] of Object.entries(props.fields)) {
|
|
if (typeof val === 'object' && !Array.isArray(val)) continue;
|
|
result.push({ key, val });
|
|
}
|
|
return result;
|
|
});
|
|
|
|
function updateField(key, newVal) {
|
|
props.modelValue[key] = newVal;
|
|
}
|
|
|
|
function fieldType(val) {
|
|
if (typeof val === 'boolean') return 'boolean';
|
|
if (typeof val === 'number') return 'number';
|
|
if (Array.isArray(val)) return 'array';
|
|
return 'string';
|
|
}
|
|
|
|
function removeTag(key, index) {
|
|
props.modelValue[key].splice(index, 1);
|
|
}
|
|
|
|
function addTag(key, val) {
|
|
if (!val || !val.trim()) return;
|
|
if (!Array.isArray(props.modelValue[key])) props.modelValue[key] = [];
|
|
props.modelValue[key].push(val.trim());
|
|
}
|
|
|
|
return { flatFields, updateField, fieldType, removeTag, addTag };
|
|
},
|
|
template: `
|
|
<el-card shadow="never" class="config-card">
|
|
<template #header>
|
|
<div class="config-card-header">
|
|
<span class="config-card-title">{{ label }}</span>
|
|
<span class="config-card-section">[{{ section }}]</span>
|
|
</div>
|
|
</template>
|
|
<div v-for="item in flatFields" :key="item.key"
|
|
class="config-row">
|
|
<div class="config-key">
|
|
{{ item.key }}
|
|
</div>
|
|
<div class="config-val">
|
|
<el-switch v-if="fieldType(item.val) === 'boolean'"
|
|
:model-value="modelValue[item.key]"
|
|
@update:model-value="updateField(item.key, $event)"
|
|
active-text="开" inactive-text="关" />
|
|
<el-input-number v-else-if="fieldType(item.val) === 'number'"
|
|
:model-value="modelValue[item.key]"
|
|
@update:model-value="updateField(item.key, $event)"
|
|
:step="Number.isInteger(item.val) ? 1 : 0.1"
|
|
controls-position="right" style="width: 200px" />
|
|
<div v-else-if="fieldType(item.val) === 'array'" class="config-tags">
|
|
<el-tag v-for="(tag, ti) in modelValue[item.key]" :key="ti"
|
|
closable @close="removeTag(item.key, ti)"
|
|
style="margin-bottom:2px">
|
|
{{ tag }}
|
|
</el-tag>
|
|
<el-input size="small" style="width:140px"
|
|
placeholder="回车添加"
|
|
@keyup.enter="addTag(item.key, $event.target.value); $event.target.value=''" />
|
|
</div>
|
|
<el-input v-else
|
|
:model-value="String(modelValue[item.key] ?? '')"
|
|
@update:model-value="updateField(item.key, $event)" />
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
`
|
|
};
|