<template>
<div id="app" style="color: black;">
<button @click="toggle">展开/收起</button>
<div ref="content" class="content" :style="{ maxHeight: maxHeight }">
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
</div>
</div>
</template>
<script setup>
import { ref, watch, onMounted, nextTick } from 'vue';
const isOpen = ref(false);
const maxHeight = ref('0px');
const content = ref(null);
const updateMaxHeight = async () => {
if (isOpen.value) {
// 确保DOM更新完成
await nextTick();
// 将maxHeight设置为内容实际高度
maxHeight.value = `${content.value.scrollHeight}px`;
} else {
maxHeight.value = '0';
}
};
// 观察isOpen值变化来更新maxHeight
watch(isOpen, updateMaxHeight);
// 在组件挂载后,考虑初始状态是否展开
onMounted(() => {
if (isOpen.value) updateMaxHeight();
});
function toggle() {
isOpen.value = !isOpen.value;
}
</script>
<style scoped>
.content {
overflow: hidden;
transition: max-height 0.3s ease;
}
</style>
<template>
<div id="app" style="color: black;">
<button @click="toggle">展开/收起</button>
<div ref="content" class="content" :style="{ maxHeight: `${maxHeight}` }">
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
<p>这是一个可以展开收起的内容区域。这里的内容可以根据实际情况增加或减少,高度会自动适配。</p>
</div>
</div>
</template>
<script setup>
import { ref, watch, onMounted, nextTick } from 'vue';
const isOpen = ref(false);
const maxHeight = ref('0px');
const content = ref(null);
const pxToVw = (pxValue, viewportWidth = 428) => {
if (!pxValue || !viewportWidth) {
throw new Error('Both pxValue and viewportWidth are required.');
}
// 将像素值转换为视口宽度单位的百分比
const vwValue = (pxValue / viewportWidth) * 100;
return `${vwValue.toFixed(6)}vw`; // 保留五位小数以确保精度
}
const updateMaxHeight = async () => {
if (isOpen.value) {
// 确保DOM更新完成
await nextTick();
// 将maxHeight设置为内容实际高度
maxHeight.value = pxToVw(content.value.scrollHeight)
} else {
maxHeight.value = '0';
}
};
// 观察isOpen值变化来更新maxHeight
watch(isOpen, updateMaxHeight);
// 在组件挂载后,考虑初始状态是否展开
onMounted(() => {
if (isOpen.value) updateMaxHeight();
});
function toggle() {
isOpen.value = !isOpen.value;
}
</script>
<style scoped>
.content {
overflow: hidden;
/* height: var(--dynamic-height); */
/* 使用 CSS 变量来设置高度 */
transition: max-height 0.3s ease;
/* transition: max-height 0.3s ease; */
}
</style>
第一个是正常处理
第二是项目中 使用postcss-px-to-viewport 插件 px转换vw处理