vue实现点击查看更多
Vue 实现点击查看更多功能
基础实现方案
使用 v-show 或 v-if 控制内容显示状态,通过点击事件切换状态:
<template>
<div>
<p v-show="!isExpanded">{{ truncatedText }}</p>
<p v-show="isExpanded">{{ fullText }}</p>
<button @click="toggleExpand">
{{ isExpanded ? '收起' : '查看更多' }}
</button>
</div>
</template>
<script>
export default {
data() {
return {
fullText: '这里是完整的长文本内容...',
isExpanded: false
}
},
computed: {
truncatedText() {
return this.fullText.slice(0, 100) + '...'
}
},
methods: {
toggleExpand() {
this.isExpanded = !this.isExpanded
}
}
}
</script>
动态内容截断方案
当需要处理动态内容时,可以使用 ref 获取DOM元素计算高度:
<template>
<div>
<div ref="content" :class="{ 'line-clamp': !expanded }">
{{ content }}
</div>
<button @click="expanded = !expanded">
{{ expanded ? '收起' : '查看更多' }}
</button>
</div>
</template>
<script>
export default {
props: ['content'],
data() {
return {
expanded: false
}
}
}
</script>
<style>
.line-clamp {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
</style>
列表数据加载更多
对于分页加载的场景,可以结合事件触发加载:
<template>
<div>
<ul>
<li v-for="item in visibleItems" :key="item.id">
{{ item.name }}
</li>
</ul>
<button
v-if="hasMore"
@click="loadMore"
:disabled="loading">
{{ loading ? '加载中...' : '加载更多' }}
</button>
</div>
</template>
<script>
export default {
data() {
return {
allItems: [], // 所有数据
visibleCount: 5,
loading: false
}
},
computed: {
visibleItems() {
return this.allItems.slice(0, this.visibleCount)
},
hasMore() {
return this.visibleCount < this.allItems.length
}
},
methods: {
loadMore() {
this.loading = true
// 模拟异步加载
setTimeout(() => {
this.visibleCount += 5
this.loading = false
}, 500)
}
}
}
</script>
动画过渡效果
为展开/收起添加平滑过渡:
<template>
<div>
<div class="content-wrapper">
<transition name="expand">
<p v-if="expanded" key="full">{{ text }}</p>
<p v-else key="truncated">{{ truncatedText }}</p>
</transition>
</div>
<button @click="expanded = !expanded">
{{ expanded ? '收起' : '查看更多' }}
</button>
</div>
</template>
<style>
.expand-enter-active, .expand-leave-active {
transition: all 0.3s ease;
overflow: hidden;
}
.expand-enter, .expand-leave-to {
max-height: 0;
opacity: 0;
}
.content-wrapper {
position: relative;
}
</style>
响应式截断
根据容器宽度自动计算截断位置:
<template>
<div ref="container" class="truncate-container">
<p ref="content">{{ text }}</p>
<span
v-if="needsTruncation && !expanded"
class="ellipsis">...</span>
<button
v-if="needsTruncation"
@click="expanded = !expanded">
{{ expanded ? '收起' : '查看更多' }}
</button>
</div>
</template>
<script>
export default {
data() {
return {
expanded: false,
needsTruncation: false
}
},
mounted() {
this.checkTruncation()
window.addEventListener('resize', this.checkTruncation)
},
beforeDestroy() {
window.removeEventListener('resize', this.checkTruncation)
},
methods: {
checkTruncation() {
this.$nextTick(() => {
const container = this.$refs.container
const content = this.$refs.content
this.needsTruncation = content.scrollWidth > container.offsetWidth
})
}
}
}
</script>
<style>
.truncate-container {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
padding-right: 80px;
}
.truncate-container p {
display: inline;
}
.ellipsis {
position: absolute;
right: 60px;
background: white;
}
</style>





