瀑布流布局方案

实现了一个简单的前端开发移动端瀑布流布局的方案

  1. HTML部分:

    • 页面使用了Flex布局,整体分为顶部导航栏和内容区域两部分。
    • 导航栏包含若干个导航选项,并使用Font Awesome图标库的搜索图标作为过滤器。
    • 内容区域为瀑布流布局,采用两列显示,并使用list-warpperlist-item样式。
  2. CSS部分:

    • 定义了页面的整体样式,包括顶部导航栏、瀑布流布局和列表项的样式。
    • 导航栏选项在激活和悬停时有不同的背景和颜色变化。
    • 使用Flex布局实现瀑布流布局,设置了两列,column-gap用于设置列之间的间隔。
  3. Vue.js部分:

    • 创建一个Vue实例,将其绑定到#app元素上。
    • data中定义了navListlistcurrentId三个数据。
    • navList表示导航栏的选项列表,包含idtitle字段。
    • list是一个包含20个模拟列表项的数组,每个项都有titledescimgid字段,分别表示标题、描述、图片和ID。
    • currentId用于存储当前选中的导航栏选项或列表项的ID,默认为1。
    • methods中定义了一个handleClick方法,用于处理导航栏选项或列表项的点击事件。点击时会将对应的ID赋值给currentId,实现选中状态的切换。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入vue文件 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">

    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        #app {
            display: flex;
            flex-direction: column;
            height: 100vh;
            background: #f7f7f7;
        }

        .header {
            flex-shrink: 0;
            height: 50px;
            background: #26a69a;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .content {
            flex: 1;
            display: flex;
            overflow: hidden;
            width: 100vw;
            margin-top: 10px;
        }

        .nav-warrper {
            font-family: 'Microsoft YaHei';
            font-size: 20px;
            white-space: nowrap;
            display: flex;
            align-items: center;
            height: 100%;
            padding:0 5px;
        }

        .nav-item {
            padding: 0 20px;
            color: #fff;
        }

        .nav-item.active {
            color: #000;
            background: #fff;
            transition: all .3s;
        }
        .nav-item:hover{
            background: #fff;
            color: #000;
            transition: all .3s;
            cursor: pointer;
        }

        .left {
            flex-shrink: 0;
            width: 100px;
            background: #26a69a;
        }

        .right {
            flex: 1;
            display: flex;
            flex-direction: column;
        }

        .filter {
            flex-shrink: 0;
            padding: 10px;
            background: #26a69a;
            /* 左边增加白色阴影 */
            position: relative;
        }
        .list-warpper{
            flex: 1;
            overflow: scroll;
            padding: 10px;
            column-gap: 10px;
            column-count: 2;
        }
        .list-item{
            flex-shrink: 0;
            min-width: calc(50% - 10px);
            box-sizing: border-box;
            overflow: hidden;
            align-self: flex-start;
            background-color: #fff;
            margin-bottom: 10px;
            /* 左上和右上圆角5px */
            border-top-left-radius: 5px;
            border-top-right-radius: 5px;
            /* 增加阴影 */
            box-shadow: 0 0 10px #00000030;


        }
    </style>
</head>

<body>
    <div id="app">
        <header>
            <div class="header">
                <div class="nav-warrper">
                    <div :class="item.id===currentId?'active':''" class="nav-item" v-for="item in navList" :key="item.id" @click="handleClick(item.id)">{{item.title}}</div>
                </div>
                <div class="filter">
                    <i class="fa fa-search" style="font-size:20px"></i>
                </div>
            </div>
        </header>
        <div class="content">
            <div class="list-warpper">
                <div class="list-item" v-for="item in list" :key="item.id" @click="handleClick(item.id)">
                    <div class="img-warpper">
                        <img :src="item.img" alt="">
                    </div>
                    <div class="title">{{item.title}}</div>
                    <div class="desc">{{item.desc}}</div>
                </div>
            </div>
        </div>
    </div>
</body>
<script>

    // 创建vue实例
    const app = new Vue({
        el: '#app',
        data: {
            navList: [
                { id: 1, title: '首页' },
                { id: 2, title: '分类' },
                { id: 3, title: '购物车' },
                { id: 4, title: '我的' },
            ],
            // 模拟一个列表数据,长度为20,有标题、图片、id、描述等字段
            list: Array.from({ length: 20 }).map((item, index) => {
                return {
                    title: `标题${index}`,
                    // 描述生成一个随机文字,长度10-30,用于区分不同的描述
                    desc: Array.from({ length: Math.floor(Math.random() * 100 + 10) }).map(() => {
                        return '描述'
                    }).join(''),
                    img: `https://picsum.photos/200/200?random=${index}`,
                    id: index,
                    // desc: `描述${index}`
                }
            }),
            // 用于存储当前选中的id
            currentId: 1,
        },
        methods: {
            // 点击列表项时触发
            handleClick(id) {
                // 将当前选中的id赋值给currentId
                this.currentId = id
            }
        }
    })
</script>

</html>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值