vue 实现 tag导航过多
解决方案:动态滚动与折叠菜单
当Vue项目中标签导航(Tag)数量过多时,可以采用动态滚动结合折叠菜单的方式优化显示效果。通过计算容器宽度和标签宽度,实现横向滚动或自动折叠。
核心代码示例:
<template>
<div class="tag-container" ref="container">
<div class="tag-wrapper" ref="wrapper">
<el-tag v-for="tag in visibleTags" :key="tag.path">{{ tag.title }}</el-tag>
<el-dropdown v-if="hiddenTags.length > 0">
<el-tag class="more-tags">+{{ hiddenTags.length }}</el-tag>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-for="tag in hiddenTags" :key="tag.path">
{{ tag.title }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script>
export default {
data() {
return {
allTags: [],
visibleTags: [],
hiddenTags: []
}
},
mounted() {
this.calculateVisibleTags()
window.addEventListener('resize', this.calculateVisibleTags)
},
methods: {
calculateVisibleTags() {
const containerWidth = this.$refs.container.offsetWidth
let totalWidth = 0
const tempVisibleTags = []
const tempHiddenTags = []
this.allTags.forEach(tag => {
// 假设每个标签宽度为80px(需根据实际样式调整)
const tagWidth = 80
if (totalWidth + tagWidth <= containerWidth - 50) { // 预留折叠按钮空间
tempVisibleTags.push(tag)
totalWidth += tagWidth
} else {
tempHiddenTags.push(tag)
}
})
this.visibleTags = tempVisibleTags
this.hiddenTags = tempHiddenTags
}
}
}
</script>
<style scoped>
.tag-container {
width: 100%;
overflow-x: auto;
white-space: nowrap;
}
.tag-wrapper {
display: inline-block;
}
.more-tags {
cursor: pointer;
}
</style>
优化方案:虚拟滚动技术
对于极大量标签的情况,可采用虚拟滚动技术,只渲染可视区域内的标签。需要安装vue-virtual-scroller插件:
npm install vue-virtual-scroller
实现代码:
<template>
<RecycleScroller
class="scroller"
:items="tags"
:item-size="80"
key-field="path"
horizontal
>
<template v-slot="{ item }">
<el-tag>{{ item.title }}</el-tag>
</template>
</RecycleScroller>
</template>
<script>
import { RecycleScroller } from 'vue-virtual-scroller'
export default {
components: { RecycleScroller },
data() {
return {
tags: [] // 所有标签数据
}
}
}
</script>
<style scoped>
.scroller {
height: 40px;
width: 100%;
}
</style>
响应式断点处理
通过CSS媒体查询实现不同屏幕尺寸下的自适应布局:
@media (max-width: 768px) {
.tag-container {
display: flex;
flex-wrap: wrap;
}
.tag-wrapper {
flex-wrap: wrap;
}
}
性能优化建议
- 对标签数据使用
v-if替代v-show减少初始DOM节点 - 对静态标签使用
Object.freeze()避免不必要的响应式开销 - 在Vuex或Pinia中管理标签状态,避免重复计算
- 对长时间运行的标签列表使用Web Worker处理计算逻辑
交互增强功能
添加滑动操作和关闭按钮提升用户体验:
<el-tag
v-for="tag in tags"
:key="tag.path"
closable
@close="handleClose(tag)"
@click.native="handleClick(tag)"
>
{{ tag.title }}
</el-tag>
以上方案可根据实际项目需求组合使用,建议优先考虑动态滚动与折叠菜单的组合方案,在保证功能完整性的同时获得最佳性能表现。







