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

一、前言

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

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

✅ 页面结构设计

✅ 数据绑定与渲染

✅ 列表项布局与样式优化

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

✅ 搜索功能初步实现

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

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

二、项目目标

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

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

三、项目结构说明

复制代码
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 数据

九、结语

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

相关推荐
tyqtyq221 小时前
药品说明书解读 —— AI 安全用药助手,鸿蒙原生应用深度解析
人工智能·学习·华为·生活·harmonyos
卡梅德生物科技小能手4 小时前
卡美德生物科普CSF1(巨噬细胞集落刺激因子1)
经验分享·深度学习·生活
书中枫叶4 小时前
从「上次几点喂奶」到全栈小程序:我做了个喂宝助手
mongodb·微信小程序·node.js
ssshooter5 小时前
小程序分包页面报 "has not been registered yet" 的隐蔽根因:一个动态 import 拖垮整个分包
前端·javascript·微信小程序
AI行业学习9 小时前
OpenAI Codex 完整下载 & 安装指南(2026最新版)
linux·开发语言·python·.net·notepad++
fusg18011 天前
不厚重不刺激,复盛公六味地黄酒适合长期饮用的养生酒
生活
tyqtyq221 天前
求职信生成:AI 智能求职信撰写系统的鸿蒙实现
人工智能·学习·华为·生活·harmonyos
卡梅德生物科技小能手1 天前
卡梅德生物:一文读懂核心炎症靶点TNF(肿瘤坏死因子)
经验分享·深度学习·生活
tyqtyq221 天前
营养餐单规划:AI 科学饮食规划系统的鸿蒙实现
人工智能·学习·华为·职场和发展·生活·harmonyos
fusg18011 天前
古法浸泡工艺打造的养生酒,品鉴特点是什么
生活