feat: 调整了长文本组件的渲染

This commit is contained in:
2026-05-22 13:01:09 +08:00
parent 1a331d2ae2
commit 6e0988e85a
6 changed files with 206 additions and 84 deletions

View File

@@ -1,23 +1,20 @@
<template>
<view class="parsed-value">
<template v-if="isIgnoredField"></template>
<template v-else-if="isContentBody">
<template v-for="entry in renderContentBodyEntries" :key="entry.key">
<view v-if="entry.type === 'text'" class="content-body-text">
{{ entry.value }}
</view>
<view v-else-if="entry.type === 'list'" class="content-body-list-card">
<view
v-for="(item, index) in entry.value"
:key="index"
class="content-body-list-item"
>
<view class="content-body-list-text">
{{ formatLeafValue(item) }}
</view>
<view v-if="shouldRenderField" class="parsed-value">
<template v-for="entry in renderFieldEntries" :key="entry.key">
<view v-if="entry.type === 'text'" class="content-body-text">
{{ entry.value }}
</view>
<view v-else-if="entry.type === 'list'" class="content-body-list-card">
<view
v-for="(item, index) in entry.value"
:key="index"
class="content-body-list-item"
>
<view class="content-body-list-text">
{{ formatLeafValue(item) }}
</view>
</view>
</template>
</view>
</template>
</view>
</template>
@@ -36,9 +33,7 @@ const props = defineProps({
},
});
const CONTENT_BODY_KEY = "content_body";
const HIDDEN_CONTENT_BODY_KEYS = ["container_type"];
const IGNORED_FIELD_KEYS = ["container_type"];
const IGNORED_FIELD_KEYS = ["container_type", "content", "components"];
const isArrayValue = (value) => Array.isArray(value);
@@ -52,7 +47,7 @@ const sanitizeValue = (value) => {
}
if (isObjectValue(value)) {
return Object.keys(value).reduce((result, key) => {
if (HIDDEN_CONTENT_BODY_KEYS.includes(key)) return result;
if (IGNORED_FIELD_KEYS.includes(key)) return result;
result[key] = sanitizeValue(value[key]);
return result;
}, {});
@@ -60,6 +55,17 @@ const sanitizeValue = (value) => {
return value;
};
const hasDisplayValue = (value) => {
if (value === undefined || value === null) return false;
if (typeof value === "string") return !!value.trim();
if (isArrayValue(value)) return value.some((item) => hasDisplayValue(item));
if (isObjectValue(value)) {
const valueObj = sanitizeValue(value);
return Object.keys(valueObj).some((key) => hasDisplayValue(valueObj[key]));
}
return true;
};
const formatLeafValue = (value) => {
if (value === undefined || value === null) return "";
if (typeof value === "boolean") return value ? "是" : "否";
@@ -73,35 +79,47 @@ const formatLeafValue = (value) => {
return String(value);
};
const isContentBody = computed(() => props.fieldKey === CONTENT_BODY_KEY);
const isIgnoredField = computed(() => IGNORED_FIELD_KEYS.includes(props.fieldKey));
const renderFieldEntries = computed(() => {
if (isIgnoredField.value || !hasDisplayValue(props.value)) return [];
const renderContentBodyEntries = computed(() => {
if (!isContentBody.value || !isObjectValue(props.value)) return [];
const value = sanitizeValue(props.value);
if (isArrayValue(value)) {
return [{
key: props.fieldKey,
type: "list",
value: value.filter((item) => hasDisplayValue(item)),
}];
}
return Object.keys(props.value)
.filter((key) => !HIDDEN_CONTENT_BODY_KEYS.includes(key))
.map((key) => {
const value = props.value[key];
if (isArrayValue(value)) {
if (isObjectValue(value)) {
return Object.keys(value)
.filter((key) => hasDisplayValue(value[key]))
.map((key) => {
const entryValue = value[key];
if (isArrayValue(entryValue)) {
return {
key,
type: "list",
value: entryValue.filter((item) => hasDisplayValue(item)),
};
}
return {
key,
type: "list",
value: value.filter((item) => formatLeafValue(item)),
type: "text",
value: formatLeafValue(entryValue),
};
}
return {
key,
type: "text",
value: formatLeafValue(value),
};
})
.filter((entry) => {
if (entry.type === "list") return entry.value.length > 0;
return !!entry.value;
});
});
}
return [{
key: props.fieldKey,
type: "text",
value: formatLeafValue(value),
}];
});
const isIgnoredField = computed(() => IGNORED_FIELD_KEYS.includes(props.fieldKey));
const shouldRenderField = computed(() => renderFieldEntries.value.length > 0);
</script>
<style scoped lang="scss">