Vuetify 3数据表格长文本View More功能实现问题求助
Vuetify 3 数据表格实现「View More/View Less」按钮方案
针对你遇到的两个问题,以下是完整的修复实现:
核心问题分析
- ref 管理错误:原代码中单个
descriptionRef无法区分表格中每一行的描述元素,需要用对象存储每个行对应的 DOM 引用。 - DOM 时机问题:
mounted钩子执行时表格可能还未完全渲染,需要等待 DOM 更新完成后再判断文本截断状态。 - 截断判断逻辑缺失:未实现
scrollHeight与clientHeight的比较逻辑。
完整实现代码
<template> <v-data-table :headers="headers" :items="items"> <template #item.description="{ item }"> <div class="description-wrapper"> <div :ref="el => descriptionRefs[item.name] = el" class="three_lines_description" :class="{ expanded: isExpanded[item.name] }" > {{ item.description }} </div> <v-btn v-if="isTruncated[item.name]" @click="toggleExpand(item.name)" text size="small" > {{ isExpanded[item.name] ? 'View Less' : 'View More' }} </v-btn> </div> </template> </v-data-table> </template> <script> import { nextTick, onMounted, onUnmounted, reactive } from 'vue'; export default { setup() { const headers = [ { title: "Name", key: "name" }, { title: "Email", key: "email" }, { title: "Description", key: "description" }, ]; const items = reactive([ { name: "Alice", email: "alice@example.com", description: "短描述" }, { name: "Bob", email: "bob@example.com", description: "这是一段超过三行的测试描述文本,用来验证View More按钮的显示逻辑。这是一段超过三行的测试描述文本,用来验证View More按钮的显示逻辑。这是一段超过三行的测试描述文本,用来验证View More按钮的显示逻辑。" }, { name: "Charlie", email: "charlie@example.com", description: "中等长度描述文本,刚好两行左右,不会触发View More按钮。中等长度描述文本,刚好两行左右。" } ]); const isExpanded = reactive({}); const isTruncated = reactive({}); const descriptionRefs = reactive({}); const toggleExpand = (name) => { isExpanded[name] = !isExpanded[name]; }; const checkTruncation = () => { Object.keys(descriptionRefs).forEach(name => { const el = descriptionRefs[name]; if (!el) return; // 重置展开状态,确保判断基于截断状态的高度 isExpanded[name] = false; // 等待DOM更新后再获取正确的高度 nextTick(() => { isTruncated[name] = el.scrollHeight > el.clientHeight; }); }); }; onMounted(() => { // 等待表格DOM完全渲染后执行判断 nextTick(checkTruncation); // 监听窗口大小变化,重新判断截断状态 window.addEventListener('resize', checkTruncation); }); onUnmounted(() => { window.removeEventListener('resize', checkTruncation); }); return { headers, items, isExpanded, isTruncated, toggleExpand }; } }; </script> <style scoped> .three_lines_description { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; transition: max-height 0.3s ease; max-height: calc(1.5em * 3); /* 假设行高为1.5em,可根据实际调整 */ } .three_lines_description.expanded { -webkit-line-clamp: unset; max-height: none; overflow: visible; } .description-wrapper { margin: 0.5em 0; } </style>
关键修改说明
- Ref 管理:使用
descriptionRefs对象存储每个行的 DOM 引用,通过:ref="el => descriptionRefs[item.name] = el"绑定每个描述元素。 - DOM 时机处理:在
onMounted中通过nextTick确保表格渲染完成后再执行截断判断,同时监听窗口 resize 事件,适配屏幕变化。 - 样式优化:添加
expanded类控制展开/收起状态,使用max-height配合过渡动画提升体验,明确设置三行的最大高度确保判断准确。 - 截断判断逻辑:通过比较
scrollHeight(文本完整高度)和clientHeight(容器显示高度),确定文本是否被截断,设置isTruncated状态控制按钮显示。
内容的提问来源于stack exchange,提问作者Jessica
相关产品推荐
相关产品推荐

