fix: 修复单选、多选、多行文本的只读样式

This commit is contained in:
gaoyunqi
2024-04-25 10:12:19 +08:00
parent 60ef2ca412
commit 64140ebbca
4 changed files with 381 additions and 373 deletions

View File

@ -146,6 +146,8 @@ export const basicComponents = [
typeName: t('编辑器'), typeName: t('编辑器'),
type: 'richtext-editor', type: 'richtext-editor',
options: { options: {
labelWidthMode: 'fix',
labelFixWidth: 120,
span: '', span: '',
defaultValue: '', defaultValue: '',
width: '100%', width: '100%',

View File

@ -2,13 +2,18 @@
* @Description:It is troublesome to implement radio button group in the form. So it is extracted independently as a separate component * @Description:It is troublesome to implement radio button group in the form. So it is extracted independently as a separate component
--> -->
<template> <template>
<CheckboxGroup v-bind="attrs" v-model:value="checked" button-style="solid" @change="handleChange"> <div class="api-checkbox-group">
<CheckboxGroup v-show="!disabled" v-model:value="checked" button-style="solid" v-bind="attrs" @change="handleChange">
<template v-for="item in getOptions" :key="`${item.value}`"> <template v-for="item in getOptions" :key="`${item.value}`">
<Checkbox :value="item.value" :disabled="item.disabled"> <Checkbox :disabled="item.disabled" :value="item.value">
{{ item.label }} {{ item.label }}
</Checkbox> </Checkbox>
</template> </template>
</CheckboxGroup> </CheckboxGroup>
<div v-if="disabled" class="readonly-wrap">
{{ displayText() }}
</div>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, PropType, ref, computed, unref, watch, inject, watchEffect } from 'vue'; import { defineComponent, PropType, ref, computed, unref, watch, inject, watchEffect } from 'vue';
@ -28,23 +33,23 @@
name: 'ApiCheckboxGroup', name: 'ApiCheckboxGroup',
components: { components: {
CheckboxGroup: Checkbox.Group, CheckboxGroup: Checkbox.Group,
Checkbox, Checkbox
}, },
props: { props: {
api: { api: {
type: Function as PropType<(arg?: Recordable | string) => Promise<OptionsItem[]>>, type: Function as PropType<(arg?: Recordable | string) => Promise<OptionsItem[]>>,
default: null, default: null
}, },
params: { params: {
type: [Object, String] as PropType<Recordable | string>, type: [Object, String] as PropType<Recordable | string>,
default: () => ({}), default: () => ({})
}, },
value: { value: {
type: [Array, String], type: [Array, String]
}, },
isBtn: { isBtn: {
type: [Boolean] as PropType<boolean>, type: [Boolean] as PropType<boolean>,
default: false, default: false
}, },
numberToString: propTypes.bool, numberToString: propTypes.bool,
resultField: propTypes.string.def(''), resultField: propTypes.string.def(''),
@ -57,14 +62,15 @@
// defaultValue: Array, // defaultValue: Array,
staticOptions: { staticOptions: {
type: Array as PropType<OptionsItem[]>, type: Array as PropType<OptionsItem[]>,
default: () => [], default: () => []
}, },
apiConfig: { apiConfig: {
type: Object, type: Object,
default: () => {}, default: () => {}
}, },
mainKey: String, mainKey: String,
index: Number, index: Number,
disabled: Boolean
}, },
emits: ['options-change', 'change', 'update:value'], emits: ['options-change', 'change', 'update:value'],
setup(props, { emit }) { setup(props, { emit }) {
@ -86,7 +92,7 @@
prev.push({ prev.push({
label: next[labelField], label: next[labelField],
value: numberToString ? `${value}` : value, value: numberToString ? `${value}` : value,
...omit(next, [labelField, valueField]), ...omit(next, [labelField, valueField])
}); });
} }
return prev; return prev;
@ -101,13 +107,9 @@
let val = isValidJSON(o.value); let val = isValidJSON(o.value);
let field = ''; let field = '';
if (val && val.bindTable) { if (val && val.bindTable) {
let table = !isCamelCase let table = !isCamelCase ? val.bindTable + 'List' : camelCaseString(val.bindTable + '_List');
? val.bindTable + 'List'
: camelCaseString(val.bindTable + '_List');
field = !isCamelCase ? val.bindField : camelCaseString(val.bindField); field = !isCamelCase ? val.bindField : camelCaseString(val.bindField);
formModel && formModel && formModel[table!][props.index || 0] && formModel[table!][props.index || 0][field];
formModel[table!][props.index || 0] &&
formModel[table!][props.index || 0][field];
} else if (val && val.bindField) { } else if (val && val.bindField) {
field = !isCamelCase ? val.bindField : camelCaseString(val.bindField); field = !isCamelCase ? val.bindField : camelCaseString(val.bindField);
formModel && formModel[field]; formModel && formModel[field];
@ -126,8 +128,8 @@
}, },
{ {
immediate: true, immediate: true,
deep: true, deep: true
}, }
); );
watch( watch(
@ -136,8 +138,8 @@
checked.value = typeof val === 'string' ? val?.split(',') : val; checked.value = typeof val === 'string' ? val?.split(',') : val;
}, },
{ {
immediate: true, immediate: true
}, }
); );
async function fetch() { async function fetch() {
@ -153,12 +155,7 @@
options.value = props.staticOptions; options.value = props.staticOptions;
} }
if (props.datasourceType === 'api') { if (props.datasourceType === 'api') {
options.value = await apiConfigFunc( options.value = await apiConfigFunc(props.apiConfig, isCamelCase, formModel, props.index);
props.apiConfig,
isCamelCase,
formModel,
props.index,
);
} }
} }
@ -191,13 +188,21 @@
function handleChange(value) { function handleChange(value) {
emit('update:value', value.toString()); emit('update:value', value.toString());
emit('change'); emit('change');
checked.value = checked.value = props.value === undefined || props.value === null ? value : (props.value as any).split(',');
props.value === undefined || props.value === null
? value
: (props.value as any).split(',');
} }
return { checked, getOptions, attrs, loading, t, handleChange, props }; function displayText() {
}, const _checked = checked.value;;
const labelArr = [];
(getOptions.value || []).forEach((opt) => {
if (_checked.includes(opt.value)) {
labelArr.push(opt.label);
}
});
return labelArr.join(', ');
}
return { checked, getOptions, attrs, loading, t, handleChange, props, displayText };
}
}); });
</script> </script>

View File

@ -2,22 +2,21 @@
* @Description:It is troublesome to implement radio button group in the form. So it is extracted independently as a separate component * @Description:It is troublesome to implement radio button group in the form. So it is extracted independently as a separate component
--> -->
<template> <template>
<RadioGroup <div class="api-radio-group">
v-bind="attrs" <RadioGroup v-show="!disabled" v-model:value="checked" :optionType="optionType" button-style="solid" v-bind="attrs" @change="handleChange">
v-model:value="checked"
:optionType="optionType"
button-style="solid"
@change="handleChange"
>
<template v-for="item in getOptions" :key="`${item.value}`"> <template v-for="item in getOptions" :key="`${item.value}`">
<RadioButton v-if="optionType === 'button'" :value="item.value" :disabled="item.disabled"> <RadioButton v-if="optionType === 'button'" :disabled="item.disabled" :value="item.value">
{{ item.label }} {{ item.label }}
</RadioButton> </RadioButton>
<Radio v-else :value="item.value" :disabled="item.disabled"> <Radio v-else :disabled="item.disabled" :value="item.value">
{{ item.label }} {{ item.label }}
</Radio> </Radio>
</template> </template>
</RadioGroup> </RadioGroup>
<div v-if="disabled">
{{ displayText() }}
</div>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, PropType, ref, computed, unref, watch, inject, watchEffect } from 'vue'; import { defineComponent, PropType, ref, computed, unref, watch, inject, watchEffect } from 'vue';
@ -38,23 +37,23 @@
components: { components: {
RadioGroup: Radio.Group, RadioGroup: Radio.Group,
RadioButton: Radio.Button, RadioButton: Radio.Button,
Radio, Radio
}, },
props: { props: {
api: { api: {
type: Function as PropType<(arg?: Recordable | string) => Promise<OptionsItem[]>>, type: Function as PropType<(arg?: Recordable | string) => Promise<OptionsItem[]>>,
default: null, default: null
}, },
params: { params: {
type: [Object, String] as PropType<Recordable | string>, type: [Object, String] as PropType<Recordable | string>,
default: () => ({}), default: () => ({})
}, },
value: { value: {
type: [String, Number, Boolean] as PropType<string | number | boolean>, type: [String, Number, Boolean] as PropType<string | number | boolean>
}, },
isBtn: { isBtn: {
type: [Boolean] as PropType<boolean>, type: [Boolean] as PropType<boolean>,
default: false, default: false
}, },
numberToString: propTypes.bool, numberToString: propTypes.bool,
resultField: propTypes.string.def(''), resultField: propTypes.string.def(''),
@ -66,11 +65,11 @@
optionType: propTypes.string.def('default'), optionType: propTypes.string.def('default'),
staticOptions: { staticOptions: {
type: Array as PropType<OptionsItem[]>, type: Array as PropType<OptionsItem[]>,
default: () => [], default: () => []
}, },
apiConfig: Object, apiConfig: Object,
mainKey: String, mainKey: String,
index: Number, index: Number
}, },
emits: ['options-change', 'change', 'update:value'], emits: ['options-change', 'change', 'update:value'],
setup(props, { emit }) { setup(props, { emit }) {
@ -82,6 +81,7 @@
const isCamelCase = inject<boolean>('isCamelCase', false); const isCamelCase = inject<boolean>('isCamelCase', false);
// Embedded in the form, just use the hook binding to perform form verification // Embedded in the form, just use the hook binding to perform form verification
const checked = ref<string | number>(''); const checked = ref<string | number>('');
const disabled = attrs.value.disabled;
// Processing options value // Processing options value
const getOptions = computed(() => { const getOptions = computed(() => {
const { labelField, valueField, numberToString } = props; const { labelField, valueField, numberToString } = props;
@ -91,7 +91,7 @@
prev.push({ prev.push({
label: next[labelField], label: next[labelField],
value: numberToString ? `${value}` : value, value: numberToString ? `${value}` : value,
...omit(next, [labelField, valueField]), ...omit(next, [labelField, valueField])
}); });
} }
return prev; return prev;
@ -105,14 +105,10 @@
let val = isValidJSON(o.value); let val = isValidJSON(o.value);
let field = ''; let field = '';
if (val && val.bindTable) { if (val && val.bindTable) {
let table = !isCamelCase let table = !isCamelCase ? val.bindTable + 'List' : camelCaseString(val.bindTable + '_List');
? val.bindTable + 'List'
: camelCaseString(val.bindTable + '_List');
field = !isCamelCase ? val.bindField : camelCaseString(val.bindField); field = !isCamelCase ? val.bindField : camelCaseString(val.bindField);
formModel && formModel && formModel[table!][props.index || 0] && formModel[table!][props.index || 0][field];
formModel[table!][props.index || 0] &&
formModel[table!][props.index || 0][field];
} else if (val && val.bindField) { } else if (val && val.bindField) {
field = !isCamelCase ? val.bindField : camelCaseString(val.bindField); field = !isCamelCase ? val.bindField : camelCaseString(val.bindField);
formModel && formModel[field]; formModel && formModel[field];
@ -128,7 +124,7 @@
() => { () => {
fetch(); fetch();
}, },
{ deep: true, immediate: true }, { deep: true, immediate: true }
); );
watch( watch(
@ -137,8 +133,8 @@
checked.value = val; checked.value = val;
}, },
{ {
immediate: true, immediate: true
}, }
); );
async function fetch() { async function fetch() {
@ -154,12 +150,7 @@
options.value = props.staticOptions; options.value = props.staticOptions;
} }
if (props.datasourceType === 'api') { if (props.datasourceType === 'api') {
options.value = await apiConfigFunc( options.value = await apiConfigFunc(props.apiConfig, isCamelCase, formModel, props.index);
props.apiConfig,
isCamelCase,
formModel,
props.index,
);
} }
} else { } else {
api = props.api; api = props.api;
@ -195,7 +186,17 @@
emit('change'); emit('change');
} }
return { checked, getOptions, attrs, loading, t, handleChange, props }; function displayText() {
}, const val = checked.value;
const options = getOptions.value || [];
const chkItem = options.find((item) => item.value === val);
if (chkItem) {
return chkItem.label;
}
return '';
}
return { checked, getOptions, attrs, loading, t, handleChange, props, displayText, disabled };
}
}); });
</script> </script>

View File

@ -417,7 +417,7 @@
} }
function readonlySupport(name) { function readonlySupport(name) {
return /^(Input|AutoCodeRule|DatePicker|Text|TimePicker|Range|RichTextEditor)$/.test(name); return /^(Input|AutoCodeRule|DatePicker|Text|TimePicker|Range|RichTextEditor|TimeRangePicker|RangePicker|InputTextArea)$/.test(name);
} }
function getShow(schema: FormSchema): boolean { function getShow(schema: FormSchema): boolean {