You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于用户输入的动态字体大小适配问题及代码优化求助

Vue动态字体适配问题解决+代码优化

问题分析

  1. 删除字符时内容溢出容器:原代码靠字符长度增减判断字体调整方向,还固定每次±20pt的步长,这种方式太粗糙——删除字符后可能字体调得过大直接撑破容器;而且多个if条件逻辑冲突,导致调整失效。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:21:00