npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hbis-uni/hbis-waterfall

v1.0.1

Published

HBIS UNI Waterfall Component

Readme

HbisWaterfall 瀑布流组件

简介

HbisWaterfall 是一个基于 Vue 3 开发的瀑布流布局组件,支持动态列数、动态数据加载、高度计算和自定义内容。适用于图片展示、商品列表等需要瀑布流布局的场景。

特性

  • 动态列数:支持 2 到 maxColumn 列的动态调整
  • 高度计算:根据组件宽度和图片比例计算高度,实现真正的瀑布流效果
  • 响应式布局:使用组件宽度而非屏幕宽度,适应不同容器大小
  • 自定义内容:通过插槽支持自定义图片下方的内容
  • 实时调整:支持通过滑块等控件实时调整列数和间距
  • 性能优化:只在必要时重新计算和分配数据
  • 错误处理:包含图片加载错误处理

安装

作为组件库的一部分安装

pnpm add @hbis-uni/components

单独安装

pnpm add @hbis-uni/hbis-waterfall

使用方法

基本使用

<template>
  <HbisWaterfall
    :data="waterfallData"
    :column="2"
    :max-column="5"
    :column-gap="10"
    :row-gap="10"
    image-key="url"
    item-key="id"
  />
</template>

<script setup>
import { HbisWaterfall } from '@hbis-uni/components';

const waterfallData = [
  {
    id: 'img-1',
    url: 'https://example.com/image1.jpg'
  },
  {
    id: 'img-2',
    url: 'https://example.com/image2.jpg'
  },
  // 更多数据...
];
</script>

带自定义内容的使用

<template>
  <HbisWaterfall
    ref="waterfallRef"
    :data="waterfallData"
    :column="3"
    :column-gap="15"
    :row-gap="15"
    image-key="url"
    item-key="id"
  >
    <template #default="{ item, index }">
      <div class="custom-content">
        <h3>图片 {{ index + 1 }}</h3>
        <p>描述: {{ item.description || '无描述' }}</p>
      </div>
    </template>
  </HbisWaterfall>
</template>

<script setup>
import { ref } from 'vue';
import { HbisWaterfall } from '@hbis-uni/components';

const waterfallRef = ref();
const waterfallData = [
  {
    id: 'img-1',
    url: 'https://example.com/image1.jpg',
    description: '这是一张测试图片'
  },
  // 更多数据...
];

// 手动刷新瀑布流
const refreshWaterfall = () => {
  waterfallRef.value?.refresh();
};
</script>

<style scoped>
.custom-content {
  padding: 15px;
  background-color: white;
  border-radius: 0 0 8px 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
</style>

API

属性

| 属性名 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | data | Array | [] | 瀑布流数据数组,每个元素应包含图片URL等信息 | | column | Number | 2 | 列数,最小为2 | | maxColumn | Number | 5 | 最大列数 | | columnGap | [Number, String] | 10 | 列间距(px) | | rowGap | [Number, String] | 10 | 行间距(px) | | itemKey | String | 'id' | 数据唯一键字段名 | | imageKey | String | 'url' | 图片URL字段名 |

事件

| 事件名 | 说明 | 参数 | | --- | --- | --- | | load | 图片加载成功事件 | event: Event | | error | 图片加载失败事件 | event: Event |

插槽

| 插槽名 | 说明 | 作用域变量 | | --- | --- | --- | | default | 自定义内容插槽,用于展示图片下方的内容 | { item: Object, index: Number } |

方法

| 方法名 | 说明 | 参数 | 返回值 | | --- | --- | --- | --- | | refresh | 刷新数据,重新分配到多列 | 无 | 无 |

数据结构

基本数据结构

const waterfallData = [
  {
    id: 'img-1',        // 唯一标识,对应 itemKey
    url: 'https://example.com/image1.jpg',  // 图片URL,对应 imageKey
    description: '图片描述'  // 自定义字段,可在插槽中使用
  },
  // 更多数据...
];

字段说明

  • id:数据唯一键,用于 Vue 的 v-for 渲染,可通过 itemKey 属性指定其他字段
  • url:图片URL,用于显示图片,可通过 imageKey 属性指定其他字段
  • 其他字段:可自定义添加,在插槽中通过 item 访问

示例

完整示例

<template>
  <div class="waterfall-demo">
    <h2>瀑布流组件示例</h2>
    
    <div class="controls">
      <div class="control-group">
        <label>列数: {{ column }}</label>
        <input 
          type="range" 
          v-model.number="column" 
          min="2" 
          :max="maxColumn" 
          step="1"
        />
      </div>
      
      <div class="control-group">
        <label>列间距: {{ columnGap }}px</label>
        <input 
          type="range" 
          v-model.number="columnGap" 
          min="0" 
          max="30" 
          step="1"
        />
      </div>
      
      <div class="control-group">
        <label>行间距: {{ rowGap }}px</label>
        <input 
          type="range" 
          v-model.number="rowGap" 
          min="0" 
          max="30" 
          step="1"
        />
      </div>
      
      <button @click="addMoreData">加载更多</button>
    </div>
    
    <HbisWaterfall
      ref="waterfallRef"
      :data="waterfallData"
      :column="column"
      :max-column="maxColumn"
      :column-gap="columnGap"
      :row-gap="rowGap"
      image-key="url"
      item-key="id"
      @load="handleImageLoad"
      @error="handleImageError"
    >
      <template #default="{ item, index }">
        <div class="custom-content">
          <h3>图片 {{ index + 1 }}</h3>
          <p>描述: {{ item.description }}</p>
          <p>尺寸: {{ item.width }} × {{ item.height }}</p>
        </div>
      </template>
    </HbisWaterfall>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { HbisWaterfall } from '@hbis-uni/components';

const waterfallRef = ref();
const column = ref(2);
const maxColumn = ref(5);
const columnGap = ref(10);
const rowGap = ref(10);
const waterfallData = ref([]);

// 生成测试数据
const generateTestData = (count = 20) => {
  const data = [];
  const widths = [200, 250, 300, 350, 400];
  
  for (let i = 0; i < count; i++) {
    const width = widths[Math.floor(Math.random() * widths.length)];
    const height = Math.floor(width * (0.5 + Math.random()));
    
    data.push({
      id: `img-${Date.now()}-${i}`,
      url: `https://gips1.baidu.com/it/u=3874647369,3220417986&fm=3028&app=3028&f=JPEG&fmt=auto?w=720&h=1280`,
      description: `这是第 ${i + 1} 张测试图片`,
      width,
      height
    });
  }
  return data;
};

// 加载更多数据
const addMoreData = () => {
  const newData = generateTestData(10);
  waterfallData.value = [...waterfallData.value, ...newData];
};

// 处理图片加载
const handleImageLoad = (event) => {
  console.log('图片加载成功:', event.target.src);
};

// 处理图片错误
const handleImageError = (event) => {
  console.error('图片加载失败:', event.target.src);
};

// 组件挂载
onMounted(() => {
  waterfallData.value = generateTestData(20);
});
</script>

<style scoped>
.waterfall-demo {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.controls {
  background-color: #f5f5f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
}

.control-group {
  margin-bottom: 15px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.control-group label {
  width: 120px;
  font-weight: bold;
}

.control-group input[type="range"] {
  flex: 1;
}

button {
  padding: 10px 20px;
  background-color: #409eff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #66b1ff;
}

.custom-content {
  padding: 15px;
  background-color: white;
  border-radius: 0 0 8px 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.custom-content h3 {
  margin: 0 0 10px 0;
  color: #333;
  font-size: 16px;
}

.custom-content p {
  margin: 5px 0;
  color: #666;
  font-size: 14px;
}
</style>

注意事项

  1. 数据项要求

    • 数据项必须包含唯一键(通过 itemKey 指定),用于 Vue 的 v-for 渲染
    • 数据项必须包含图片 URL(通过 imageKey 指定),用于显示图片
  2. 性能优化

    • 当数据量较大时,建议使用虚拟滚动或分页加载
    • 图片建议使用适当的尺寸,避免过大的图片影响加载性能
  3. 布局注意事项

    • 组件容器应设置适当的宽度,以便组件能够正确计算列宽
    • 当容器宽度变化时,组件会自动重新计算布局
  4. 兼容性

    • 支持 Vue 3 项目和 Uniapp 项目
    • 在 Uniapp 中使用时,注意平台差异(如样式前缀等)

浏览器兼容性

  • Chrome >= 60
  • Firefox >= 55
  • Safari >= 12
  • Edge >= 79
  • 支持现代移动浏览器

贡献

欢迎提交 Issue 和 Pull Request 来改进这个组件。

许可证

ISC