在图片网站中,通常是使用瀑布流的方式来显示图片,等宽度不等高,这样显得错落有致
今天 使用Vue3
实现一个瀑布流组件,并发布为一个npm
包
grid
布局- 支持响应式
参考自react-plock
1、window.matchMedia
window.matchMedia(mediaQueryString)
方法返回一个MediaQueryList
对象,表示指定css
媒体查询字符串的结果
其中参数mediaQueryString
表示CSS @media
规则的任何媒体查询选项,比如:
min-width
、min-height
、orientation
等
const media = window.matchMedia("(max-width: 850px)")
在MediaQueryList
对象中有两个属性:
matches
:返回查询结果,是一个布尔值media
:媒体查询的字符串
所以,根据matches
我们就可以知道是否命中当前的媒体查询选项
并且,我们还可以通过addEventListener
监听mediaQuery
查询结果的变化
media.removeEventListener('change', () => {
console.log(media.matches)
});
2、瀑布流组件
响应式控制
根据屏幕大小确定图片的列数
export interface PropConfigType {
gap: number[]; // 行列的间距
columns: number[]; // 不同媒体查询选项对应的列数
medias?: number[]; // 媒体查询选项
}
import { reactive, onUnmounted } from 'vue';
export function useMediaValues(config: PropConfigType) {
const info = reactive({
columns: 1,
gap: 1
});
const { columns, gap, media } = config;
if (!media) {
return setInfo(0);
}
// 循环查询medias
const mediaQueries = media.map(media =>
window.matchMedia(`(min-width: ${media}px)`)
);
const onSizeChange = () => {
// 记录匹配到的哪一个media
let matches = 0;
mediaQueries.forEach(mediaQuery => {
mediaQuery.matches && matches++;
});
// 优先匹配后面的
const idx = Math.min(mediaQueries.length - 1, matches);
setInfo(idx);
};
onSizeChange();
// 监听查询结果
for (let mediaQuery of mediaQueries) {
mediaQuery.addEventListener('change', onSizeChange);
}
onUnmounted(() => {
for (let mediaQuery of mediaQueries) {
mediaQuery.removeEventListener('change', onSizeChange);
}
});
function setInfo(idx: number) {
info.columns = columns[idx];
info.gap = gap[idx];
return info;
}
return info;
}
数据结构
info.columns
计算出瀑布流的数据结构,每列为一个数组,并存储到dataColumns
通过for
循环将fall-row
给渲染出来
当屏幕宽度变化时,会重新计算info.columns
,得到一个新的dataColumms
,渲染等到新的瀑布流界面
// fall-row组件
// 用户的内容通过插槽的形式添加
// water-fall 组件
// 此处为作用域插槽
- 通过作用域插槽将图片的
src
传递给父组件
3、使用
// 导入组件
import { waterFall } from ...
v-slot="slotProps"
访问父组件的作用域,获取到src
进行显示
需要注意的是:columns
、gap
、medias
的个数要一致
发布npm
包
做好工程化后,就可以通过发布为npm
包
地址:vue3-plock
现在可以通过依赖命令来安装了
pnpm add vue3-plock
点击codesandbox查看线上的运行
源码已经上传github,欢迎start
参考: