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

一、前言

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

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

✅ 页面结构设计

✅ 数据绑定与渲染

✅ 列表项布局与样式优化

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

✅ 搜索功能初步实现

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

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

二、项目目标

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

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

三、项目结构说明

复制代码
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.jswx.request() 请求
图片懒加载 使用 mode="lazy" 或自定义组件
地理定位 调用 wx.getLocation() 获取位置
评分显示 使用自定义组件或 CSS 星级评分
骨架屏优化 使用 <skeleton> 组件提升用户体验

七、常见问题与解决方案

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

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

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

九、结语

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

相关推荐
知识分享小能手17 小时前
uni-app 入门学习教程,从入门到精通,uni-app 企业项目实战:鲁嗑瓜子项目开发知识点(9)
前端·javascript·学习·微信小程序·小程序·uni-app·vue
知识分享小能手17 小时前
uni-app 入门学习教程,从入门到精通,uni-app中uCharts组件学习((8)
vue.js·学习·ui·微信小程序·小程序·uni-app·echarts
社会底层无业大学生19 小时前
uniapp微信小程序简单表格展示
微信小程序·小程序·uni-app·vue·1024程序员节
從南走到北19 小时前
JAVA无人自助共享系统台球室源码自助开台约球交友系统源码小程序
java·微信·微信小程序·小程序·1024程序员节
WLJT12312312321 小时前
生活电器:重构家居体验的产业变革与发展探索
大数据·人工智能·科技·生活
彷徨而立21 小时前
【生活】秋冬季节,鼻子很干结痂,扣掉鼻孔干痂流血,鼻塞等护理方法
生活
菜鸟una1 天前
【微信小程序 + 消息订阅 + 授权】 微信小程序实现消息订阅流程介绍,代码示例(仅前端)
前端·vue.js·微信小程序·小程序·typescript·taro·1024程序员节
科技宅说2 天前
OPARTMENT发布Light 系列 以“光”重塑都市青年生活方式
大数据·人工智能·生活
AGI_Eval2 天前
美团 LongCat 团队发布 VitaBench:基于复杂生活场景的交互式 Agent 评测基准
生活
從南走到北2 天前
JAVA国际版一对一视频交友视频聊天系统源码支持H5 + APP
java·微信·微信小程序·小程序·音视频·交友