基于用户输入的动态字体大小适配问题及代码优化求助
Vue动态字体适配问题解决+代码优化
问题分析
- 删除字符时内容溢出容器:原代码靠字符长度增减判断字体调整方向,还固定每次±20pt的步长,这种方式太粗糙——删除字符后可能字体调得过大直接撑破容器;而且多个if条件逻辑冲突,导致调整失效。
- if语句冗余:重复判断字符长度和宽度,逻辑碎成多块,可读性差,维护麻烦。
优化方案
核心思路是根据容器和内容的实时宽度对比,动态计算刚好适配的字体大小,替代原有的步进式调整和冗余判断。具体实现:
- 移除基于字符长度的无效判断,直接对比DOM宽度;
- 用循环逐步调整字体,保证适配精度;
- 统一逻辑,简化代码结构。
优化后的完整代码
<script setup> import { ref, watch, nextTick } from "vue"; const names = ref("Jane & John Doe"); const fontSize = ref(40); const maxFontSize = ref(120); const minFontSize = ref(12); // 可选:限制最小字体,避免过小影响阅读 const title = ref(); const innerTitle = ref(); // 字体适配核心函数 const adjustFontSize = async () => { await nextTick(); // 等待DOM更新,确保拿到最新的宽度值 if (!title.value || !innerTitle.value) return; const containerWidth = title.value.clientWidth; let currentSize = maxFontSize.value; // 先拉到最大字体,再逐步缩小到刚好适配(比从小往大调更可靠) innerTitle.value.style.fontSize = `${currentSize}pt`; await nextTick(); // 内容超宽时,逐步缩小字体 while (innerTitle.value.clientWidth > containerWidth && currentSize > minFontSize.value) { currentSize -= 1; innerTitle.value.style.fontSize = `${currentSize}pt`; await nextTick(); } // 可选:内容过窄时,尝试放大到最大适配值 while (innerTitle.value.clientWidth < containerWidth && currentSize < maxFontSize.value) { const testSize = currentSize + 1; innerTitle.value.style.fontSize = `${testSize}pt`; await nextTick(); if (innerTitle.value.clientWidth <= containerWidth) { currentSize = testSize; } else { break; } } fontSize.value = currentSize; }; // 监听输入内容变化,触发适配 watch(names, () => adjustFontSize()); // 组件挂载完成后初始化适配 adjustFontSize(); </script> <template> <input v-model="names" /> <div size="A4"> <div ref="title" style="background: green; padding: 0 50px;" class="title"> <div ref="innerTitle" style="background: blue; white-space: nowrap;" :style="{ fontSize: `${fontSize}pt` }" > {{ names }} </div> </div> </div> </template> <style scoped> body { background: rgb(204, 204, 204); } .title { display: block; margin: 0 auto; text-align: center; width: 80%; /* 给外层容器明确宽度,方便测试 */ } </style>
关键改进点
- 精准适配:通过循环逐步调整字体,确保内容刚好贴合容器,避免步长过大导致的溢出或留白;
- 逻辑简化:移除所有冗余if判断,用循环逻辑替代,代码更简洁易读;
- DOM时机处理:用
nextTick确保每次调整后获取最新DOM宽度,避免旧值导致判断错误; - 边界控制:增加最小字体限制,替换原代码中
+100的硬编码内边距,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Neval Mayer
相关产品推荐
相关产品推荐

