实现仅当内容超两行时显示/隐藏Read More/Hide按钮
问题与解决方案
问题
开发类YouTube评论区时,需实现仅当评论内容超过两行时显示「查看更多/收起」按钮的逻辑。当前已通过computedLineclamp实现内容截断,按钮展开/收起功能正常,但无法判断内容行数来控制按钮显示。
解决方案
核心思路是通过对比DOM元素的scrollHeight(内容实际高度)和clientHeight(容器可见高度)来判断内容是否被截断:
- 当
scrollHeight > clientHeight时,说明内容超过两行,显示按钮 - 否则隐藏按钮
具体实现步骤
- 给评论内容的
<p>标签添加ref属性,用于获取DOM元素 - 在组件
mounted钩子中调用判断方法,同时监听content属性变化(避免内容更新后判断失效) - 新增判断方法,更新控制按钮显示的变量
- 调整按钮的
v-show逻辑,结合判断变量和展开状态
修改后的完整代码
Template部分
<template> <div> <div class="d-flex flex-row align-items-center"> <h4 class="card-title">{{ author }}</h4> <h6 class="card-subtitle text-muted ml-3"> {{ timeAgo(createdAt) }} ago </h6> </div> <p class="multiline" ref="commentContent" :style="{'-webkit-line-clamp': computedLineclamp }" > <b class="timestamp" v-if="timestamp !== null" > @{{ timeToHHMMSS(timestamp) }} </b> {{ content }} </p> <div> <base-button v-show="!readmore && isContentOverflow" @click="changeLineclamp()" link class="text-white p-0" size="sm" > 查看更多 </base-button> <base-button v-show="readmore" @click="hideContent()" link class="text-white p-0" size="sm" > 收起 </base-button> </div> </div> </template>
Script部分
<script> // Internal modules import { timeSince, toHHMMSS } from "@/plugins/timeControls.js"; export default { name: "comment-item", data() { return { lineclamp: 2, readmore: false, isContentOverflow: false, // 标记内容是否溢出 } }, props: { id: { type: String, required: true, }, author: { type: String, required: true, }, createdAt: { type: Number, required: true, }, timestamp: { type: Number, required: true, }, content: { type: String, required: true, } }, mounted() { this.checkContentOverflow(); }, watch: { // 监听内容变化,重新判断是否溢出 content() { this.readmore = false; // 内容更新后重置展开状态 this.lineclamp = 2; this.$nextTick(() => { this.checkContentOverflow(); }); } }, methods: { checkContentOverflow() { const contentEl = this.$refs.commentContent; if (!contentEl) return; // 对比实际高度和可见高度,判断是否溢出 this.isContentOverflow = contentEl.scrollHeight > contentEl.clientHeight; }, changeLineclamp() { this.lineclamp = 'initial'; this.readmore = true; }, hideContent() { this.lineclamp = 2; this.readmore = false; // 收起后重新判断(避免窗口大小变化导致判断失效) this.$nextTick(() => { this.checkContentOverflow(); }); }, timeAgo(date) { return timeSince(date); }, timeToHHMMSS(time) { return toHHMMSS(time); }, }, computed: { computedLineclamp() { return this.lineclamp; }, }, }; </script>
Style部分
<style lang="scss" scoped> @import "@/assets/sass/dashboard/custom/_variables.scss"; ul { list-style-type: none; padding: 0; } .timestamp { color: $primary; } .multiline { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; } </style>
关键说明
checkContentOverflow方法:通过DOM元素高度对比,准确判断内容是否超过两行watch监听content:确保内容更新后重新执行判断逻辑$nextTick:确保DOM更新完成后再获取元素高度,避免判断不准确
内容的提问来源于stack exchange,提问作者dounia
相关产品推荐
相关产品推荐

