Appearance
调试半天,原来一个插件就能搞定流式布局,还是能自定义那种
今天开发一个首页,领导表示要百度图片那种效果,能长能短,能满满当当的填充整个页面。
好久没有鼓捣这种东西了,原来流式布局这么简单。
css解决方案
使用 CSS Grid + grid-auto-rows 实现简易流式布局,不依赖 JS,简洁易维护。
html
<div class="card-conatiner">
<div class="card-item">内容</div>
</div>
<style>
.card-conatiner {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}
.card-item {
transition: all 0.3s ease;
}
</style>
但是这个方案缺陷比较多,虽然简单,但是没办法覆盖动态宽高的情况。而且这里内容是图片的话,还存在加载以后样式错乱的问题。
Masonry.js插件一步解决
费了半天劲,结果效果不是太好。上网一搜,竟然有个插件专门解决这个问题。
shell
# 安装
npm install masonry-layout
html
<template>
<div ref="gridContainer" class="grid">
<div v-for="(item, index) in cards" :key="index" class="grid-item">
内容
</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue';
import Masonry from 'masonry-layout';
const cards = ref([
{ title: '卡片1', content: '这是扩展内容...', expanded: false },
{ title: '卡片2', content: '更多文字内容...', expanded: false },
]);
const gridContainer = ref(null);
let msnry = null;
const toggleExpand = async (index) => {
cards.value[index].expanded = !cards.value[index].expanded;
await nextTick(); // 等待 DOM 更新
msnry.layout(); // 重新计算布局
};
onMounted(() => {
msnry = new Masonry(gridContainer.value, {
itemSelector: '.grid-item',
columnWidth: 250,
gutter: 16,
percentPosition: true,
});
});
</script>
<style scoped>
.grid {
margin: 0 auto;
}
.grid-item {
width: 250px;
margin-bottom: 16px;
}
</style>
效果非常棒,而且配置简单。
简单罗列一下API:
js
{
itemSelector: '.grid-item', //附加选择器,用来指定哪些元素包裹的元素会重新排列。
columnWidth: 200, //1列网格的宽度,单位为像素(px), 默认: 第一个浮动元素外宽度。
percentPosition:true, //将元素定位设成百分比。true后,元素宽度自动适应容器的尺寸变化。
gutter: 10, //元素水平方向的间隙
horizontalOrder: true,
singleMode: false,
//禁用测量每个浮动元素的宽度。如浮动元素具有相同的宽度,设为true。默认 false。
resizeable: true, // 绑定一个Masonry访问,窗口resize时布局平滑流动。默认:true。
animate: true, // 布局重排动画。默认:false。
animationOptions: {},
//一对动画选项,具体参数可以参考jquery .animate()中的options选项。
appendedContent: $('.new_content'),
// 附加选择器元素,用来尾部追加内容。
// 在集成infinitescroll插件的情况下使用。
saveOptions: true,
// 默认情况下,Masonry 将使用以前Masonry使用过的参数选项,所以你只需要输入一次选项。
// 默认:true
stamp:'.grid-stamp',
// 网格中的固定元素,不会因重新布局改变位置,移动元素填充到固定元素下方
fitWidth: true, // 设置网格容器宽度等于网格宽度,这样配合css的auto margin实现居中显示
originLeft: true, // 默认true网格左对齐,设为false变为右对齐
originTop: true, // 默认true网格对齐顶部,设为false对齐底部
containerStyle: { position: 'relative' }, // 设置容器样式
stagger: '0.03s',
//重布局时网格并不是一起变换的,排在后面的网格比前一个延迟开始,该项设置延迟时间
initLayout: true, //初始化布局,设未true可手动初试化布局
}