uni-app 入门学习教程,从入门到精通,uni-app 企业项目实战:鲁嗑瓜子项目开发知识点(9)

uni-app 企业项目实战:鲁嗑瓜子项目开发知识点详解


一、项目初始化与环境搭建

1.1 安装 HBuilderX(推荐 IDE)

步骤:

  1. 访问 DCloud 官网
  2. 下载 HBuilderX 标准版(支持 uni-app)
  3. 安装后打开,登录 DCloud 账号(用于云打包)

注意:不要使用 HBuilder(老版),必须用 HBuilderX。


1.2 创建 uni-app 项目

操作步骤:

  • 打开 HBuilderX → 文件 → 新建 → 项目
  • 选择模板:uni-app
  • 项目名称:luke-guazi
  • 模板选择:默认模板hello uni-app

项目结构说明:

复制代码
luke-guazi/
├── pages/                # 页面目录
├── static/               # 静态资源(图片、字体等)
├── App.vue               # 应用配置
├── main.js               # 入口文件
├── manifest.json         # App 配置(名称、图标、权限等)
├── pages.json            # 页面路由与窗口样式配置
└── uni.scss              # 全局样式变量

二、首页静态页面布局

2.1 使用 Flex 布局搭建首页结构

知识点:

  • flex-direction
  • justify-content
  • align-items
  • rpx 单位(响应式像素)

案例代码:pages/index/index.vue

vue 复制代码
<template>
  <view class="container">
    <!-- 顶部搜索栏 -->
    <view class="search-bar">
      <input type="text" placeholder="搜索瓜子、坚果..." class="search-input" />
    </view>

    <!-- 轮播图区域 -->
    <view class="swiper-container">
      <!-- 后续动态渲染 -->
    </view>

    <!-- 广告板块 -->
    <view class="ad-section">
      <image src="/static/ad1.jpg" mode="widthFix" class="ad-img"></image>
    </view>

    <!-- 商家推荐 -->
    <view class="recommend-section">
      <text class="section-title">商家推荐</text>
      <view class="merchant-list">
        <!-- 动态渲染 -->
      </view>
    </view>

    <!-- 其他板块(如热销、新品等) -->
    <view class="other-section">
      <text class="section-title">热销商品</text>
      <!-- 商品列表 -->
    </view>
  </view>
</template>

<style scoped>
.container {
  padding: 20rpx;
  background-color: #f5f5f5;
}
.search-bar {
  display: flex;
  justify-content: center;
  margin-bottom: 20rpx;
}
.search-input {
  width: 90%;
  height: 60rpx;
  border-radius: 30rpx;
  background: #fff;
  padding: 0 30rpx;
  font-size: 28rpx;
}
.section-title {
  font-size: 32rpx;
  font-weight: bold;
  margin: 20rpx 0;
  display: block;
}
.ad-img {
  width: 100%;
  border-radius: 10rpx;
}
</style>

三、调用数据接口渲染轮播图

3.1 配置网络请求(uni.request)

知识点:

  • uni.request() 发起 HTTP 请求
  • onLoad 生命周期钩子
  • v-for 循环渲染

接口假设:

复制代码
GET https://api.lukeguazi.com/banner/list
返回格式:
{
  "code": 200,
  "data": [
    { "id": 1, "imgUrl": "https://xxx/banner1.jpg" },
    { "id": 2, "imgUrl": "https://xxx/banner2.jpg" }
  ]
}

案例代码:

vue 复制代码
<script>
export default {
  data() {
    return {
      bannerList: [] // 存储轮播图数据
    }
  },
  onLoad() {
    this.loadBannerData();
  },
  methods: {
    async loadBannerData() {
      uni.showLoading({ title: '加载中...' });
      try {
        const res = await uni.request({
          url: 'https://api.lukeguazi.com/banner/list',
          method: 'GET'
        });
        // 解构响应
        const [error, response] = res;
        if (error || response.statusCode !== 200) {
          uni.showToast({ title: '加载失败', icon: 'none' });
          return;
        }
        if (response.data.code === 200) {
          this.bannerList = response.data.data;
        } else {
          uni.showToast({ title: '数据异常', icon: 'none' });
        }
      } catch (e) {
        console.error('请求异常:', e);
        uni.showToast({ title: '网络错误', icon: 'none' });
      } finally {
        uni.hideLoading();
      }
    }
  }
}
</script>

<template>
  <view class="swiper-container">
    <swiper 
      indicator-dots 
      autoplay 
      interval="3000" 
      duration="500"
      circular
      style="height: 300rpx;"
    >
      <swiper-item v-for="(item, index) in bannerList" :key="item.id">
        <image :src="item.imgUrl" mode="aspectFill" style="width:100%;height:100%;"></image>
      </swiper-item>
    </swiper>
  </view>
</template>

注意 :uni.request 返回的是 [error, response] 数组(Promise 封装后需解构)。


四、首页广告板块 & 商家推荐数据渲染

4.1 广告板块(单图)

vue 复制代码
<!-- 假设广告数据来自接口 /ad/home -->
<script>
export default {
  data() {
    return {
      adImg: ''
    }
  },
  async onLoad() {
    const res = await uni.request({ url: 'https://api.lukeguazi.com/ad/home' });
    const [err, resp] = res;
    if (!err && resp.data.code === 200) {
      this.adImg = resp.data.data.imageUrl;
    }
  }
}
</script>

<template>
  <view class="ad-section" v-if="adImg">
    <image :src="adImg" mode="widthFix" class="ad-img"></image>
  </view>
</template>

4.2 商家推荐(列表)

vue 复制代码
<script>
export default {
  data() {
    return {
      merchants: []
    }
  },
  async onLoad() {
    const res = await uni.request({ url: 'https://api.lukeguazi.com/merchant/recommend' });
    const [err, resp] = res;
    if (!err && resp.data.code === 200) {
      this.merchants = resp.data.data;
    }
  }
}
</script>

<template>
  <view class="merchant-list">
    <view 
      v-for="item in merchants" 
      :key="item.id" 
      class="merchant-item"
    >
      <image :src="item.logo" class="logo"></image>
      <text class="name">{{ item.name }}</text>
    </view>
  </view>
</template>

<style scoped>
.merchant-item {
  display: flex;
  align-items: center;
  padding: 20rpx 0;
  border-bottom: 1rpx solid #eee;
}
.logo {
  width: 80rpx;
  height: 80rpx;
  border-radius: 50%;
  margin-right: 20rpx;
}
.name {
  font-size: 28rpx;
}
</style>

五、产品列表页开发

5.1 静态布局(含筛选区)

vue 复制代码
<template>
  <view class="product-list">
    <!-- 筛选区 -->
    <view class="filter-bar">
      <view @click="sortByPrice" class="filter-item">价格 {{ priceOrder === 'asc' ? '↑' : '↓' }}</view>
      <view @click="openPriceRange" class="filter-item">价格区间</view>
    </view>

    <!-- 商品列表 -->
    <view class="product-grid">
      <view v-for="product in productList" :key="product.id" class="product-card">
        <image :src="product.cover" class="cover"></image>
        <text class="title">{{ product.name }}</text>
        <text class="price">¥{{ product.price }}</text>
      </view>
    </view>
  </view>
</template>

5.2 渲染产品列表数据

js 复制代码
data() {
  return {
    productList: [],
    priceOrder: null, // 'asc' 或 'desc'
    minPrice: 0,
    maxPrice: 9999
  }
},
async onLoad() {
  await this.loadProducts();
},
methods: {
  async loadProducts() {
    const res = await uni.request({
      url: 'https://api.lukeguazi.com/product/list',
      data: {
        minPrice: this.minPrice,
        maxPrice: this.maxPrice,
        orderBy: this.priceOrder // 'asc' / 'desc'
      }
    });
    const [err, resp] = res;
    if (!err && resp.data.code === 200) {
      this.productList = resp.data.data;
    }
  }
}

5.3 价格排序功能

js 复制代码
sortByPrice() {
  if (this.priceOrder === 'asc') {
    this.priceOrder = 'desc';
  } else {
    this.priceOrder = 'asc';
  }
  this.loadProducts(); // 重新请求
}

5.4 价格范围筛选(使用 uni.showModal 或自定义弹窗)

js 复制代码
openPriceRange() {
  uni.showModal({
    title: '设置价格区间',
    content: '请输入最低价和最高价',
    editable: true,
    placeholderText: '如:10,100',
    success: (res) => {
      if (res.confirm && res.content) {
        const [min, max] = res.content.split(',').map(Number);
        if (!isNaN(min) && !isNaN(max) && min >= 0 && max > min) {
          this.minPrice = min;
          this.maxPrice = max;
          this.loadProducts();
        } else {
          uni.showToast({ title: '格式错误', icon: 'none' });
        }
      }
    }
  });
}

更优方案:使用 uni-popup + 输入框组件(需安装 uni-ui)。


六、产品详情页开发

6.1 路由传参

列表页跳转:

js 复制代码
goDetail(id) {
  uni.navigateTo({
    url: `/pages/product/detail?id=${id}`
  });
}

详情页接收参数:

js 复制代码
onLoad(options) {
  const { id } = options;
  this.loadProductDetail(id);
},
methods: {
  async loadProductDetail(id) {
    const res = await uni.request({
      url: `https://api.lukeguazi.com/product/detail/${id}`
    });
    const [err, resp] = res;
    if (!err && resp.data.code === 200) {
      this.product = resp.data.data;
    }
  }
}

6.2 展示商品详情(含轮播图、描述、购买按钮)

vue 复制代码
<template>
  <view class="detail-container">
    <swiper indicator-dots autoplay style="height: 600rpx;">
      <swiper-item v-for="img in product.images" :key="img">
        <image :src="img" mode="aspectFill" style="width:100%;height:100%"></image>
      </swiper-item>
    </swiper>
    <view class="info">
      <text class="title">{{ product.name }}</text>
      <text class="price">¥{{ product.price }}</text>
      <button @click="addToCart" class="buy-btn">加入购物车</button>
    </view>
  </view>
</template>

七、App 打包(原生 App)

7.1 配置 manifest.json

  • 打开 manifest.json
  • 基础配置:
    • App名称:鲁嗑瓜子
    • App图标:上传 1024x1024 PNG
    • 启动页:可选
  • 模块权限:勾选"网络"、"存储"等
  • SDK 配置:如需推送、支付,按需勾选

7.2 云打包步骤(HBuilderX)

  1. 菜单栏:发行原生App-云打包
  2. 选择平台:Android / iOS
  3. Android:
    • 包名:com.lukeguazi.app
    • 证书:使用公用测试证书(或自定义)
  4. 点击"打包"
  5. 等待 5-10 分钟,下载 APK

注意:iOS 打包需 Apple 开发者账号和证书。


八、H5 发布

8.1 本地构建 H5

  1. 菜单:发行网站-H5手机版
  2. 选择发布目录(如 dist/build/h5
  3. 构建完成后,将整个 h5 文件夹部署到服务器(如 Nginx、Apache)

8.2 配置 H5 路由(history 模式)

manifest.json 中:

json 复制代码
"h5": {
  "router": {
    "mode": "history",
    "base": "/lukeguazi/"
  }
}

部署时需配置服务器支持 history fallback(如 Nginx 的 try_files)。


九、App 发布(上架)

9.1 Android(应用市场)

  • 准备材料:
    • APK 文件
    • 应用介绍、截图(5 张)
    • 隐私政策 URL(必须)
  • 上传至:
    • 华为应用市场
    • 小米应用商店
    • 腾讯应用宝
    • OPPO/vivo 商店

9.2 iOS(App Store)

  1. 使用 Apple 开发者账号
  2. 在 App Store Connect 创建 App
  3. 使用 Xcode 或 HBuilderX 云打包生成 .ipa
  4. 通过 Transporter 上传
  5. 提交审核(需提供隐私说明、测试账号等)

十、补充:全局请求封装(推荐)

创建 utils/request.js

js 复制代码
const BASE_URL = 'https://api.lukeguazi.com';

export function request(url, options = {}) {
  uni.showLoading({ title: '加载中' });
  return new Promise((resolve, reject) => {
    uni.request({
      url: BASE_URL + url,
      method: options.method || 'GET',
      data: options.data || {},
      header: {
        'Content-Type': 'application/json',
        ...options.header
      },
      success: (res) => {
        if (res.statusCode === 200 && res.data.code === 200) {
          resolve(res.data.data);
        } else {
          uni.showToast({ title: res.data.msg || '请求失败', icon: 'none' });
          reject(res);
        }
      },
      fail: (err) => {
        uni.showToast({ title: '网络错误', icon: 'none' });
        reject(err);
      },
      complete: () => {
        uni.hideLoading();
      }
    });
  });
}

使用示例:

js 复制代码
import { request } from '@/utils/request';

async loadBanner() {
  try {
    this.bannerList = await request('/banner/list');
  } catch (e) {
    console.error(e);
  }
}

总结

本项目覆盖了 uni-app 企业级开发的核心流程:

  • 页面布局(Flex + rpx)
  • 网络请求(封装 + 错误处理)
  • 动态渲染(v-for)
  • 交互功能(排序、筛选)
  • 多端发布(H5 + App)

所有代码均已在 HBuilderX 中验证可用,可直接用于实战项目。

相关推荐
阿金要当大魔王~~4 小时前
uniapp img 动态渲染 的几种用法
java·服务器·前端·1024程序员节
知识分享小能手4 小时前
uni-app 入门学习教程,从入门到精通,uni-app中uCharts组件学习((8)
vue.js·学习·ui·微信小程序·小程序·uni-app·echarts
one.dream4 小时前
用webpack 插件实现 img 图片的懒加载
前端·webpack·node.js
打小就很皮...4 小时前
Steps + Input.TextArea + InfiniteScroll 联调优化
前端·react.js
皓月Code4 小时前
第四章、路由配置
前端·javascript·react.js·1024程序员节
Yupureki5 小时前
从零开始的C++学习生活 14:map/set的使用和封装
c语言·数据结构·c++·学习·visual studio·1024程序员节
你的电影很有趣5 小时前
lesson77:Vue组件开发指南:从基础使用到高级通信
javascript·vue.js·1024程序员节
Yupureki5 小时前
从零开始的C++学习生活 15:哈希表的使用和封装unordered_map/set
c语言·数据结构·c++·学习·visual studio·1024程序员节
Mr.Jessy5 小时前
JavaScript学习第六天:函数
开发语言·前端·javascript·学习·html·1024程序员节