微信小程序案例 - 本地生活(列表页面)

一、前言

随着微信小程序的普及,越来越多的生活服务类应用开始基于微信小程序进行开发。其中,"本地生活"类小程序(如美食、团购、周边游等)因其贴近用户日常需求而广受欢迎。

本篇文章将以一个 "本地生活列表页面" 的实际案例为例,手把手带你实现一个完整的 微信小程序本地生活类首页列表页面,包括:

✅ 页面结构设计

✅ 数据绑定与渲染

✅ 列表项布局与样式优化

✅ 下拉刷新与上拉加载更多

✅ 搜索功能初步实现

✅ 真实数据模拟与静态化处理

并通过完整代码示例帮助你掌握如何在微信小程序中构建一个高性能、可扩展的本地生活类页面。

二、项目目标

我们将实现一个类似大众点评或美团风格的本地生活首页,主要包含以下功能模块:

模块 功能描述
头部搜索栏 支持关键词搜索
分类导航 如美食、外卖、电影、旅游等分类图标
商品列表 展示商家信息(图片、名称、评分、价格等)
上拉加载 支持分页加载更多商品
下拉刷新 手动刷新数据

三、项目结构说明

复制代码
project/
├── app.js
├── app.json
├── app.wxss
├── pages/
│   └── index/
│       ├── index.js
│       ├── index.json
│       ├── index.wxml
│       └── index.wxss
└── utils/
    └── mockData.js

我们使用了 mockData.js 来模拟后端接口返回的数据,便于快速开发调试。

四、页面结构搭建

✅ 1. index.wxml 结构

XML 复制代码
<view class="container">
  <!-- 搜索栏 -->
  <view class="search-bar">
    <input class="search-input" placeholder="请输入关键词搜索" bindinput="onInput"/>
  </view>

  <!-- 分类导航 -->
  <scroll-view scroll-x class="category-scroll">
    <view wx:for="{{categories}}" wx:key="id" class="category-item">
      <image src="{{item.icon}}" mode="aspectFit" class="category-icon"/>
      <text>{{item.name}}</text>
    </view>
  </scroll-view>

  <!-- 商品列表 -->
  <view class="goods-list">
    <block wx:for="{{goodsList}}" wx:key="id">
      <view class="goods-item">
        <image src="{{item.image}}" class="goods-image"/>
        <view class="goods-info">
          <text class="goods-title">{{item.title}}</text>
          <text class="goods-desc">{{item.desc}}</text>
          <text class="goods-price">¥{{item.price}}</text>
        </view>
      </view>
    </block>
  </view>

  <!-- 加载提示 -->
  <view wx:if="{{loading}}" class="loading">正在加载...</view>
</view>

✅ 2. index.wxss 样式定义

css 复制代码
.container {
  padding: 20rpx;
}

.search-bar {
  margin-bottom: 20rpx;
}

.search-input {
  height: 60rpx;
  border: 1rpx solid #ccc;
  border-radius: 8rpx;
  padding: 0 20rpx;
}

.category-scroll {
  white-space: nowrap;
  display: flex;
  overflow-x: auto;
}

.category-item {
  display: inline-block;
  text-align: center;
  margin-right: 40rpx;
  width: 120rpx;
}

.category-icon {
  width: 80rpx;
  height: 80rpx;
  margin-bottom: 10rpx;
}

.goods-list {
  border-top: 1rpx solid #eee;
}

.goods-item {
  display: flex;
  padding: 20rpx 0;
  border-bottom: 1rpx solid #eee;
}

.goods-image {
  width: 160rpx;
  height: 160rpx;
  margin-right: 20rpx;
  border-radius: 8rpx;
}

.goods-info {
  flex: 1;
  flex-direction: column;
  justify-content: space-between;
}

.goods-title {
  font-size: 28rpx;
  font-weight: bold;
}

.goods-desc {
  color: #666;
  font-size: 24rpx;
  margin-top: 10rpx;
}

.goods-price {
  color: red;
  font-size: 28rpx;
  margin-top: 10rpx;
}

.loading {
  text-align: center;
  margin-top: 20rpx;
}

五、数据绑定与交互逻辑

✅ 1. mockData.js 模拟数据

javascript 复制代码
// utils/mockData.js
module.exports = {
  categories: [
    { id: 1, name: '美食', icon: 'https://example.com/icon-food.png' },
    { id: 2, name: '外卖', icon: 'https://example.com/icon-takeout.png' },
    { id: 3, name: '电影', icon: 'https://example.com/icon-movie.png' },
    { id: 4, name: '旅游', icon: 'https://example.com/icon-travel.png' }
  ],
  goodsList: [
    { id: 1, title: '肯德基', desc: '新品套餐限时优惠', price: 29.9, image: 'https://example.com/goods1.jpg' },
    { id: 2, title: '麦当劳', desc: '经典汉堡组合', price: 35.5, image: 'https://example.com/goods2.jpg' },
    { id: 3, title: '海底捞', desc: '火锅套餐特惠', price: 98.0, image: 'https://example.com/goods3.jpg' }
  ]
};

✅ 2. index.js 逻辑控制

javascript 复制代码
const mockData = require('../../utils/mockData');

Page({
  data: {
    categories: mockData.categories,
    goodsList: [],
    loading: false,
    page: 1
  },

  onLoad() {
    this.loadGoods();
  },

  // 输入事件
  onInput(e) {
    const keyword = e.detail.value;
    console.log('输入关键字:', keyword);
    // TODO: 过滤 goodsList 或请求接口
  },

  // 加载商品数据
  loadGoods() {
    this.setData({ loading: true });
    setTimeout(() => {
      const newGoods = [...this.data.goodsList, ...mockData.goodsList];
      this.setData({
        goodsList: newGoods,
        page: this.data.page + 1,
        loading: false
      });
    }, 1000);
  },

  // 上拉加载
  onReachBottom() {
    this.loadGoods();
  },

  // 下拉刷新
  onPullDownRefresh() {
    this.setData({
      goodsList: [],
      page: 1
    });
    this.loadGoods();
    wx.stopPullDownRefresh();
  }
});

六、功能扩展建议

功能 实现方式
接入真实 API 替换 mockData.js 为 wx.request() 请求
图片懒加载 使用 mode="lazy" 或自定义组件
地理定位 调用 wx.getLocation() 获取位置
评分显示 使用自定义组件或 CSS 星级评分
骨架屏优化 使用 <skeleton> 组件提升用户体验

七、常见问题与解决方案

问题 原因 解决方案
列表不更新 数据未正确绑定 检查 setData 是否正确调用
滚动加载失效 未触发 onReachBottom 设置 page.json 中 onReachBottomDistance
图片无法加载 路径错误或跨域 使用 HTTPS 资源并检查网络权限
搜索框无响应 未绑定 bindinput 检查事件名是否拼写正确
页面样式错乱 未启用 rpx 单位 确保使用 rpx 而非 px

八、总结对比表:关键功能实现一览

功能 技术点
搜索框输入 bindinput 事件
分类滚动 scroll-view + flex
商品列表渲染 wx:for + setData
上拉加载 onReachBottom
下拉刷新 onPullDownRefresh + wx.stopPullDownRefresh
数据绑定 data + setData
模拟数据 require 引入 JSON 数据

九、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
星光开发者21 小时前
基于决策树随机森林算法的小说推荐系统的设计与实现-计算机毕设【课程设计】78485
vue.js·算法·微信小程序·django·php·课程设计·express
故七月1 天前
本地生活 GEO 内容质量风控体系构建 —— 基于陕西金贝儿母婴家政项目,万域智瞰 GEO 实践
人工智能·生活
QQ_21696290961 天前
基于微信小程序的智能膳食分析系统
java·大数据·spring boot·微信小程序·小程序·旅游
QQ_21696290961 天前
基于C#(Asp.net)电竞陪玩信息管理系统的设计与实现
java·大数据·spring boot·微信小程序·c#·云计算·asp.net
微三云马玮均—GEO源码系统 私有化部署2 天前
消费返物业费:消费+服务趋势的必然产物!
大数据·人工智能·物联网·区块链·生活
梦幻精灵_cq2 天前
*《樵坪烟雨》——雨雾云烟比齐天,樵坪绰绰画前川
生活
humors2213 天前
【转帖】居家办公如何合理用眼
生活·职场·健康·视力·用眼·眼睛·近视
吠品3 天前
CSS图片模糊过渡:一个transition加filter就够
java·数据库·notepad++
m0_462803883 天前
名单制签到怎么落地:拆解“仅名单内人员签到“的配置链路与匹配逻辑
微信小程序
特立独行的猫a3 天前
八零后熟悉的世界,正在一点点消失
程序人生·生活