Vue 列表截断组件:vue-truncate-list

76 阅读3分钟

vue-truncate-list

在前端开发中,列表展示是最常见的需求之一。但当列表内容过多时,如何优雅地处理长列表展示成为了一个挑战。今天要介绍的 vue-truncate-list 组件,正是为解决这一问题而生的强大工具。

组件简介

vue-truncate-list 是一个灵活的 Vue 组件,同时支持 Vue 2 和 Vue 3 框架,专为移动端和桌面端设计。它的核心能力是实现列表的智能截断,并支持完全自定义的截断器渲染。无论是需要展示商品列表、评论列表还是其他类型的内容列表,该组件都能帮助你轻松实现优雅的截断效果,提升用户体验。

核心功能亮点

1. 自动列表截断

组件能够动态检测列表内容,自动隐藏溢出的列表项,无需手动计算高度或数量,极大简化了长列表处理的逻辑。

2. 自定义截断器

提供完全自由的截断器 UI 渲染能力。你可以根据项目风格自定义截断显示的内容,例如常见的 +3 more 样式,或者更复杂的交互按钮。

3. 响应式设计

内置响应式机制,能够根据容器尺寸自动调整截断策略,在手机、平板、桌面等不同设备上都能呈现最佳效果。

4. 可扩展列表

支持展开 / 折叠功能,用户可以通过点击截断器来查看完整列表内容,适用于需要展示部分内容但保留查看全部选项的场景。

安装指南

通过 npm 安装

npm install @twheeljs/vue-truncate-list

通过 yarn 安装

yarn add @twheeljs/vue-truncate-list

使用示例

基础用法

下面是一个基础的列表截断示例,通过 renderTruncator 自定义截断器的显示:

<template>
  <TruncateList
    :renderTruncator="({ hiddenItemsCount }) => h('div', { class: 'listItem' }, `+${hiddenItemsCount}`)"
  >
    <div class="listItem">Item 1</div>
    <div class="listItem">Item 2</div>
    <div class="listItem">Item 3</div>
    <!-- 更多列表项... -->
  </TruncateList>
</template>
<script>
import { h } from 'vue'
import TruncateList from '@twheeljs/vue-truncate-list'
export default {
  components: {
    TruncateList
  }
}
</script>

在这个示例中,我们通过 h 函数创建了一个简单的截断器,显示隐藏项的数量。

可扩展列表用法

更复杂的可展开 / 折叠列表示例:

<template>
  <TruncateList 
    :class="['list', 'expandable', expanded ? 'expanded' : '']" 
    :alwaysShowTruncator="true"
    :renderTruncator="({ hiddenItemsCount, truncate }) => {
      if (hiddenItemsCount > 0) {
        return h(
          'button',
          {
            class: 'expandButton',
            onClick: () => {
              handleExpand();
              // 重要:使用 nextTick 确保布局重计算后调用 truncate
              nextTick(() => {
                truncate();
              })
            }
          },
          `${hiddenItemsCount} more...`
        );
      } else {
        return h(
          'button',
          {
            class: 'expandButton',
            onClick: handleCollapse
          },
          'hide'
        );
      }
    }"
  >
    <div class="listItem">foo</div>
    <!-- 更多列表项... -->
    <div class="listItem">thud</div>
  </TruncateList>
</template>
<script>
import { h, ref, nextTick } from 'vue'
import TruncateList from '@twheeljs/vue-truncate-list'
export default {
  components: {
    TruncateList
  },
  setup() {
    const expanded = ref(false);
    const handleExpand = () => {
      expanded.value = true;
    }
    const handleCollapse = () => {
      expanded.value = false;
    }
    return {
      expanded,
      handleExpand,
      handleCollapse
    }
  }
}
</script>

注意事项:当设置 expanded 类时,虽然将 max-height 设置为 none,但容器高度不会立即更新,导致 ResizeObserver 不会触发。因此,需要在 nextTick 中手动调用 truncate() 方法来确保布局重新计算。

API 参考

Props

名称类型默认值描述
renderTruncator({ hiddenItemsCount, truncate }) => stringVNode用于渲染截断器 UI 的函数,接收 hiddenItemsCount(隐藏项数量)和 truncate(重新计算布局的函数)
alwaysShowTruncatorbooleanfalse是否始终显示截断器,即使没有隐藏项

贡献与开发

本地开发

# 安装依赖
npm install
# 启动开发服务器
npm run dev

提交规范

项目使用 commitlint 来规范提交信息,请使用以下命令进行提交:

npm run commit
# 或
npx cz

版本发布

使用 release-it 进行版本发布:

npm run release

结语

vue-truncate-list 组件通过简洁的 API 和强大的功能,为 Vue 开发者提供了处理长列表展示的最佳实践。无论是移动端还是桌面端应用,它都能帮助你实现优雅的列表截断效果,提升用户体验。

项目灵感来源于 maladr0it/react-truncate-list,在此表示感谢。

欢迎大家贡献代码、提交 Issues 或提出改进建议!