瀑布流介绍
瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。逐渐在国内流行开来。国内大多数清新站基本为这类风格。
一般使用的网站类型有:
- 图片画廊:展示不同尺寸的图片,自动调整布局。
- 博客文章:以瀑布流形式展示博客文章摘要,提高阅读体验。
- 电商产品列表:展示不同类别和尺寸的产品,增强用户浏览体验。
- 社交媒体内容:展示用户生成的内容,如帖子、评论等,形成动态的瀑布流布局。
比如: 小红书首页作品的展示, 壁纸软件的壁纸展示等等..
介绍
react-masonry-css
是一个用于创建快速、响应式瀑布流布局的 React 组件,充分利用 CSS 和 React 的虚拟 DOM 渲染。
与现有的解决方案(如 DeSandro Masonry)相比,react-masonry-css
无需依赖 jQuery 或其他库,避免了多次渲染导致的性能问题。它使用简单的接口和少量的 CSS,通过指定断点来排列元素。
该组件支持 IE 10 及以上版本,无任何外部依赖,且与现有的 CSS 动画兼容。尽管不支持不同宽度元素的布局和基于高度的排序,但其性能和浏览器兼容性使其成为创建流畅、可靠布局的理想选择。
基本使用
安装
shell
npm install react-masonry-css pnpm install react-masonry-css yarn add react-masonry-css
基本使用
导入
jsx
import Masonry from "react-masonry-css";
定义一个图片列表数组,其中里面每一项都是一个包含id和图片url 的对象
jsx
const images = [ { id: 1, url: "https://images.unsplash.com/photo-1532009324734-20a7a5813719?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80", }, { id: 2, url: "https://th.bing.com/th/id/OIP.Kumuo3P82ekHloWvUs8JGQHaEK?w=272&h=180&c=7&r=0&o=5&dpr=1.1&pid=1.7", }, { id: 4, url: "https://th.bing.com/th/id/OIP.VT2BYdpsayqVZi3oxolhowHaEK?w=329&h=185&c=7&r=0&o=5&dpr=1.1&pid=1.7", }, { id: 5, url: "https://th.bing.com/th/id/OIP.FLCWWMNXRHWZRHXnwf2F3gHaCF?w=311&h=98&c=7&r=0&o=5&dpr=1.1&pid=1.7", }, { id: 6, url: "https://images.unsplash.com/photo-1532009324734-20a7a5813719?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=84", }, { id: 8, url: "https://th.bing.com/th/id/OIP.VT2BYdpsayqVZi3oxolhowHaEK?w=329&h=185&c=7&r=0&o=5&dpr=1.1&pid=1.7", }, { id: 9, url: "https://th.bing.com/th/id/OIP.FLCWWMNXRHWZRHXnwf2F3gHaCF?w=311&h=98&c=7&r=0&o=5&dpr=1.1&pid=1.7", }, { id: 10, url: "https://images.unsplash.com/photo-1532009324734-20a7a5813719?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=84", }, ];
定义断点配置项
jsx
const breakpointColumnsObj = { default: 4, 1100: 3, 700: 2, 500: 1, };
说明
- default: 4:
- 默认情况下(即屏幕宽度大于所有定义的断点时),将内容分为 4 列。
- 1100: 3:
- 当屏幕宽度小于或等于 1100 像素时,将内容分为 3 列。
- 700: 2:
- 当屏幕宽度小于或等于 700 像素时,将内容分为 2 列。
- 500: 1:
- 当屏幕宽度小于或等于 500 像素时,将内容分为 1 列。
定义Masonry组件
jsx
<Masonry breakpointCols={breakpointColumnsObj} className={WaterfallStyle.myMasonryGrid} columnClassName={WaterfallStyle.myMasonryGridColumn} > {images.map((item, index) => { console.log(item.id); return ( <img key={index} src={item.url} alt={item} style={{ width: "100%", display: "block" }} // 为什么这里需要修改this指向 onClick={() => goTodetail(item.id)} /> ); })} </Masonry>
最后需要添加上样式代码(官方文档也有说明)
创建一个index.module.css文件, 然后在该文件引入
css
.myMasonryGrid { margin-top: 2rem; display: -webkit-box; /* Not needed if autoprefixing */ display: -ms-flexbox; /* Not needed if autoprefixing */ display: flex; /* gutter size offset */ width: auto; } .myMasonryGridColumn { padding-left: 1rem; /* gutter size */ background-clip: padding-box; } /* Style your items */ .myMasonryGridColumn>img { /* change div to reference your elements you put in <Masonry> */ margin-bottom: 1rem; }
效果
最后页面应该是:
看起来还很不错, 只需要配置一点点代码, 便可以实现, 非常适合小项目的快速开发.
在我这个项目中, 这个组件的image
, 获取来源于父组件的传递
jsx
// 定义存储壁纸的state const [images, setImages] = useState([]); // 渲染完毕之后 请求接口拿数据 const getHot20Data = async () => { const res = await getHot20(); setImages(res); }; useEffect(() => { getHot20Data(); }, []); <Waterfall images={images}></Waterfall>