Vue3初始加载时文本截断判断逻辑mounted不生效问题
解决mounted阶段文本截断判断不生效的问题
问题原因
- DOM渲染时机问题:
mounted钩子执行时,data?.information对应的DOM内容可能还未完成渲染,或者浏览器还没完成元素的布局计算,导致scrollHeight和clientHeight的对比结果不准确。 - watch语法错误:原代码里
immediate: true写在了回调函数外面,属于语法错误,导致watch的初始触发逻辑没生效。
具体解决方案
1. 修复watch配置,确保初始触发
把immediate: true放到watch的第三个参数配置项里,让watch在组件初始化时就执行一次回调。
2. 利用nextTick在mounted后等待DOM渲染完成
在mounted钩子中用nextTick等待浏览器完成DOM更新和布局计算,再执行截断判断逻辑。
3. (可选)修正class绑定逻辑
原代码中isExpanded ? 'truncate' : ''逻辑可能反了——应该是未展开时添加截断类,展开时移除,否则展开状态下还是截断,不符合预期。
修改后的完整代码
SCRIPT
import { ref, watch, onMounted, nextTick } from 'vue' const information = ref<HTMLElement | null>(null) const isTextTruncated = ref(false) const isExpanded = ref(false) const data = ref({ information: '' }) // 假设是响应式数据 const toggleCtaLabel = ref('展开/收起') // 正确配置watch,监听data.information的变化,immediate初始触发 watch(() => data.value.information, () => { informationRefStatus() }, { immediate: true }) function informationRefStatus() { if (!information.value) return const element = information.value isTextTruncated.value = element.scrollHeight > element.clientHeight } onMounted(async () => { // 等待DOM完全渲染、布局完成后再计算 await nextTick() informationRefStatus() }) // 如果data是异步请求获取的,在请求成功后也要调用一次 // 比如: // async function fetchData() { // const res = await api.getInfo() // data.value = res // await nextTick() // informationRefStatus() // }
TEMPLATE
<div> <!-- 修正class绑定:未展开时应用截断样式 --> <div ref="information" :class="!isExpanded ? 'truncate' : ''"> {{ data?.information }} </div> <span v-if="isTextTruncated" @click="isExpanded = !isExpanded" > {{ toggleCtaLabel }} </span> </div>
额外注意事项
- 确保
truncate类的CSS样式正确:/* 单行截断示例 */ .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* 多行截断示例(根据需求调整行数) */ .truncate { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; } - 如果
data是异步加载的,必须在数据更新后等待nextTick再执行判断,否则DOM还没更新,计算结果依然不准确。
内容的提问来源于stack exchange,提问作者Pianoc
相关产品推荐
相关产品推荐

