解决 cl-read-more 动态内容不显示展开问题

This commit is contained in:
icssoa
2025-09-16 09:38:34 +08:00
parent 8a9fdff913
commit 3dcdf36a69
3 changed files with 66 additions and 31 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "cool-unix", "name": "cool-unix",
"version": "8.0.24", "version": "8.0.25",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"build-ui": "node ./uni_modules/cool-ui/scripts/generate-types.js", "build-ui": "node ./uni_modules/cool-ui/scripts/generate-types.js",

View File

@@ -3,18 +3,26 @@
<!-- 内容区域 --> <!-- 内容区域 -->
<view class="cl-read-more__wrapper" :class="[pt.wrapper?.className]" :style="wrapperStyle"> <view class="cl-read-more__wrapper" :class="[pt.wrapper?.className]" :style="wrapperStyle">
<view class="cl-read-more__content" :class="[pt.content?.className]"> <view class="cl-read-more__content" :class="[pt.content?.className]">
<slot></slot> <slot>
<cl-text
:pt="{
className: pt.contentText?.className
}"
>{{ content }}</cl-text
>
</slot>
</view> </view>
<view <view
class="cl-read-more__mask" class="cl-read-more__mask"
:class="[ :class="[
{ {
'is-show': !isExpanded && showToggle, 'is-show': !isExpanded && isHide,
'is-dark': isDark 'is-dark': isDark
}, },
pt.mask?.className pt.mask?.className
]" ]"
v-if="showMask"
></view> ></view>
</view> </view>
@@ -29,7 +37,7 @@
pt.toggle?.className pt.toggle?.className
]" ]"
@tap="toggle" @tap="toggle"
v-if="showToggle" v-if="showToggle && isHide"
> >
<cl-text <cl-text
color="primary" color="primary"
@@ -46,7 +54,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, getCurrentInstance, ref, onMounted, watch } from "vue"; import { computed, getCurrentInstance, ref, onMounted, watch, nextTick } from "vue";
import { getPx, isDark, parsePt } from "@/cool"; import { getPx, isDark, parsePt } from "@/cool";
import type { PassThroughProps } from "../../types"; import type { PassThroughProps } from "../../types";
import { t } from "@/locale"; import { t } from "@/locale";
@@ -67,6 +75,11 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: false default: false
}, },
// 内容
content: {
type: String,
default: ""
},
// 收起状态下的最大高度 // 收起状态下的最大高度
height: { height: {
type: [Number, String], type: [Number, String],
@@ -96,6 +109,16 @@ const props = defineProps({
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false default: false
},
// 显示切换按钮
showToggle: {
type: Boolean,
default: true
},
// 显示遮罩
showMask: {
type: Boolean,
default: true
} }
}); });
@@ -114,6 +137,7 @@ type PassThrough = {
className?: string; className?: string;
wrapper?: PassThroughProps; wrapper?: PassThroughProps;
content?: PassThroughProps; content?: PassThroughProps;
contentText?: PassThroughProps;
mask?: PassThroughProps; mask?: PassThroughProps;
toggle?: PassThroughProps; toggle?: PassThroughProps;
}; };
@@ -127,14 +151,14 @@ const isExpanded = ref(props.modelValue);
// 内容实际高度 // 内容实际高度
const contentHeight = ref(0); const contentHeight = ref(0);
// 是否显示切换按钮 // 是否隐藏内容
const showToggle = ref(true); const isHide = ref(true);
// 包裹器样式 // 包裹器样式
const wrapperStyle = computed(() => { const wrapperStyle = computed(() => {
const style = {}; const style = {};
if (showToggle.value) { if (isHide.value) {
style["height"] = isExpanded.value ? `${contentHeight.value}px` : `${props.height}rpx`; style["height"] = isExpanded.value ? `${contentHeight.value}px` : `${props.height}rpx`;
} }
@@ -156,38 +180,48 @@ function toggle() {
} }
/** /**
* 获取内容实际高度 * 获取内容高度
*/ */
function getContentHeight() { function getContentHeight() {
uni.createSelectorQuery() nextTick(() => {
.in(proxy) uni.createSelectorQuery()
.select(".cl-read-more__content") .in(proxy)
.boundingClientRect((node) => { .select(".cl-read-more__content")
// 获取内容高度 .boundingClientRect((node) => {
contentHeight.value = (node as NodeInfo).height ?? 0; // 获取内容高度
contentHeight.value = (node as NodeInfo).height ?? 0;
// 实际高度是否大于折叠高度 // 实际高度是否大于折叠高度
showToggle.value = contentHeight.value > getPx(props.height); isHide.value = contentHeight.value > getPx(props.height);
}) })
.exec(); .exec();
});
} }
// 监听modelValue变化
watch(
computed(() => props.modelValue),
(val: boolean) => {
isExpanded.value = val;
}
);
// 组件挂载后获取内容高度
onMounted(() => { onMounted(() => {
getContentHeight(); // 监听modelValue变化
watch(
computed(() => props.modelValue),
(val: boolean) => {
isExpanded.value = val;
}
);
// 监听content变化
watch(
computed(() => props.content),
() => {
getContentHeight();
},
{
immediate: true
}
);
}); });
// 暴露方法
defineExpose({ defineExpose({
toggle toggle,
getContentHeight
}); });
</script> </script>

View File

@@ -241,4 +241,5 @@ declare type ClMarqueeComponentPublicInstance = {
declare type ClReadMoreComponentPublicInstance = { declare type ClReadMoreComponentPublicInstance = {
toggle(): void; toggle(): void;
getContentHeight(): void;
}; };