uni-app开发微信小程序

本文涉及的产品
性能测试 PTS,5000VUM额度
注册配置 MSE Nacos/ZooKeeper,118元/月
函数计算FC,每月15万CU 3个月
简介: 本文详细介绍如何使用 uni-app 开发微信小程序,涵盖需求分析、架构思路及实施方案。主要功能包括用户登录、商品列表展示、商品详情、购物车及订单管理。技术栈采用 uni-app、uView UI 和 RESTful API。文章通过具体示例代码展示了从初始化项目、配置全局样式到实现各页面组件及 API 接口的全过程,并提供了完整的文件结构和配置文件示例。此外,还介绍了微信授权登录及后端接口模拟方法,确保项目的稳定性和安全性。通过本教程,读者可快速掌握使用 uni-app 开发微信小程序的方法。

1. 需求分析

随着移动互联网的发展,微信小程序已经成为了一种非常流行的应用形式。uni-app 是一种使用 Vue.js 开发所有前端应用的框架,它支持一次开发多端部署,包括微信小程序、H5、App 等。本文将详细介绍如何使用 uni-app 开发微信小程序,并通过一个简单的示例来展示整个开发过程。
image.png

主要需求点

  • 用户登录:支持微信授权登录。
  • 商品列表:展示商品信息。
  • 商品详情:展示商品详情信息。
  • 购物车功能:用户可以将商品加入购物车。
  • 订单功能:用户可以提交订单并查看订单状态。

2. 架构思路

技术栈

  • 前端框架:uni-app
  • UI库:uView UI
  • 后端接口:基于 RESTful API 的接口

核心组件

  • 页面组件:首页、商品列表页、商品详情页、购物车页、订单页。
  • API接口:获取商品列表、获取商品详情、添加商品到购物车、提交订单等。
  • 状态管理:使用 Vuex 管理全局状态。
  • 路由管理:使用 Vue Router 管理页面路由。

3. 实施方案

步骤一:初始化项目

  1. 安装 Node.js 和 HBuilderX。
  2. 使用 HBuilderX 创建一个 uni-app 项目。
npm install -g @dcloudio/uni-cli
uni init myApp
cd myApp
npm install

步骤二:安装 uView UI

npm install uview-ui --save

步骤三:配置全局样式

main.js 中引入 uView UI:

import uView from 'uview-ui';
Vue.use(uView);

步骤四:创建页面组件

  1. 首页:展示商品列表。
  2. 商品列表页:展示商品列表。
  3. 商品详情页:展示商品详情信息。
  4. 购物车页:展示购物车中的商品。
  5. 订单页:展示订单信息。

步骤五:实现 API 接口

  1. 获取商品列表/api/products
  2. 获取商品详情/api/products/:id
  3. 添加商品到购物车/api/cart
  4. 提交订单/api/orders

步骤六:实现页面逻辑

  1. 首页:展示商品列表。
  2. 商品列表页:获取商品列表并展示。
  3. 商品详情页:获取商品详情并展示。
  4. 购物车页:展示购物车中的商品。
  5. 订单页:展示订单信息。

4. 案例分享

示例代码

文件结构

├── pages/
│   ├── index/
│   │   ├── index.vue
│   │   └── index.json
│   ├── products/
│   │   ├── products.vue
│   │   └── products.json
│   ├── product-detail/
│   │   ├── product-detail.vue
│   │   └── product-detail.json
│   ├── cart/
│   │   ├── cart.vue
│   │   └── cart.json
│   └── orders/
│       ├── orders.vue
│       └── orders.json
├── static/
├── components/
├── common/
├── store/
├── main.js
└── app.json

页面组件

首页 index/index.vue

<template>
  <view class="container">
    <view class="title">商品列表</view>
    <u-cell-group>
      <u-cell-item v-for="product in products" :key="product.id" @click="goToProductDetail(product)">
        {
  
  { product.name }}
      </u-cell-item>
    </u-cell-group>
  </view>
</template>

<script>
export default {
  data() {
    return {
      products: []
    };
  },
  onLoad() {
    this.fetchProducts();
  },
  methods: {
    async fetchProducts() {
      const response = await this.$http.get('/api/products');
      this.products = response.data;
    },
    goToProductDetail(product) {
      uni.navigateTo({
        url: `/pages/product-detail/product-detail?id=${product.id}`
      });
    }
  }
};
</script>

<style>
.container {
  padding: 20px;
}

.title {
  font-size: 20px;
  margin-bottom: 10px;
}
</style>

商品列表页 products/products.vue

<template>
  <view class="container">
    <view class="title">商品列表</view>
    <u-list>
      <u-list-item v-for="product in products" :key="product.id" @click="goToProductDetail(product)">
        <view slot="title">{
  
  { product.name }}</view>
        <view slot="desc">价格:{
  
  { product.price }}元</view>
      </u-list-item>
    </u-list>
  </view>
</template>

<script>
export default {
  data() {
    return {
      products: []
    };
  },
  onLoad() {
    this.fetchProducts();
  },
  methods: {
    async fetchProducts() {
      const response = await this.$http.get('/api/products');
      this.products = response.data;
    },
    goToProductDetail(product) {
      uni.navigateTo({
        url: `/pages/product-detail/product-detail?id=${product.id}`
      });
    }
  }
};
</script>

<style>
.container {
  padding: 20px;
}

.title {
  font-size: 20px;
  margin-bottom: 10px;
}
</style>

商品详情页 product-detail/product-detail.vue

<template>
  <view class="container">
    <view class="title">{
  
  { product.name }}</view>
    <view class="details">
      <view>价格:{
  
  { product.price }}元</view>
      <view>描述:{
  
  { product.description }}</view>
      <u-button type="primary" @click="addToCart">加入购物车</u-button>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      product: {}
    };
  },
  onLoad(options) {
    this.fetchProduct(options.id);
  },
  methods: {
    async fetchProduct(id) {
      const response = await this.$http.get(`/api/products/${id}`);
      this.product = response.data;
    },
    addToCart() {
      this.$store.commit('addProductToCart', this.product);
      uni.showToast({
        title: '已加入购物车',
        icon: 'success'
      });
    }
  }
};
</script>

<style>
.container {
  padding: 20px;
}

.title {
  font-size: 20px;
  margin-bottom: 10px;
}

.details {
  margin-top: 10px;
}
</style>

购物车页 cart/cart.vue

<template>
  <view class="container">
    <view class="title">购物车</view>
    <u-list>
      <u-list-item v-for="product in cartItems" :key="product.id">
        <view slot="title">{
  
  { product.name }}</view>
        <view slot="desc">价格:{
  
  { product.price }}元</view>
      </u-list-item>
    </u-list>
    <u-button type="primary" @click="submitOrder">提交订单</u-button>
  </view>
</template>

<script>
export default {
  computed: {
    cartItems() {
      return this.$store.state.cart;
    }
  },
  methods: {
    submitOrder() {
      this.$store.commit('submitOrder');
      uni.showToast({
        title: '订单提交成功',
        icon: 'success'
      });
    }
  }
};
</script>

<style>
.container {
  padding: 20px;
}

.title {
  font-size: 20px;
  margin-bottom: 10px;
}
</style>

Vuex 状态管理

store/index.js

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
   
   
  state: {
   
   
    cart: []
  },
  mutations: {
   
   
    addProductToCart(state, product) {
   
   
      state.cart.push(product);
    },
    submitOrder(state) {
   
   
      console.log('Submitting order:', state.cart);
      state.cart = [];
    }
  }
});

API 接口

common/api.js

export default {
   
   
  async getProducts() {
   
   
    const response = await fetch('/api/products');
    return response.json();
  },
  async getProduct(id) {
   
   
    const response = await fetch(`/api/products/${
     
     id}`);
    return response.json();
  }
};

配置文件

app.json

{
   
   
  "pages": [
    "pages/index/index",
    "pages/products/products",
    "pages/product-detail/product-detail",
    "pages/cart/cart",
    "pages/orders/orders"
  ],
  "window": {
   
   
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "微信小程序商城",
    "navigationBarTextStyle": "black"
  },
  "tabBar": {
   
   
    "color": "#7A7E83",
    "selectedColor": "#3cc51f",
    "borderStyle": "black",
    "list": [
      {
   
   
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "static/home.png",
        "selectedIconPath": "static/home_selected.png"
      },
      {
   
   
        "pagePath": "pages/products/products",
        "text": "商品",
        "iconPath": "static/products.png",
        "selectedIconPath": "static/products_selected.png"
      },
      {
   
   
        "pagePath": "pages/cart/cart",
        "text": "购物车",
        "iconPath": "static/cart.png",
        "selectedIconPath": "static/cart_selected.png"
      },
      {
   
   
        "pagePath": "pages/orders/orders",
        "text": "订单",
        "iconPath": "static/orders.png",
        "selectedIconPath": "static/orders_selected.png"
      }
    ]
  },
  "networkTimeout": {
   
   
    "request": 10000,
    "downloadFile": 10000
  },
  "debug": true
}

微信授权登录

common/auth.js

import {
   
    getUserInfo } from '@uni_modules/uni-id-pages/api/user';

export default {
   
   
  async login() {
   
   
    try {
   
   
      const result = await getUserInfo();
      console.log('User info:', result);
      // 可以在这里处理登录后的逻辑,如保存用户信息等
    } catch (error) {
   
   
      console.error('Login error:', error);
    }
  }
};

后端接口模拟

mock/api.js

const products = [
  {
   
   
    id: 1,
    name: '苹果',
    price: 5,
    description: '新鲜水果,口感脆甜。'
  },
  {
   
   
    id: 2,
    name: '香蕉',
    price: 3,
    description: '新鲜水果,口感香甜。'
  },
  {
   
   
    id: 3,
    name: '橙子',
    price: 4,
    description: '新鲜水果,口感酸甜。'
  }
];

export default {
   
   
  async getProducts() {
   
   
    return products;
  },
  async getProduct(id) {
   
   
    return products.find(product => product.id === parseInt(id));
  }
};

集成到项目中

修改 main.js

import Vue from 'vue';
import App from './App.vue';
import uView from 'uview-ui';
import store from './store';
import api from './common/api';
import auth from './common/auth';

Vue.config.productionTip = false;
Vue.prototype.$http = api;
Vue.use(uView);

new Vue({
   
   
  store,
  render: h => h(App)
}).$mount('#app');

// 初始化登录
auth.login();

运行项目

  1. 在 HBuilderX 中打开项目。
  2. 点击编译并预览。
  3. 使用微信开发者工具查看效果。

运行结果

运行上述代码后,可以看到以下效果:

  • 首页展示商品列表。
  • 商品列表页展示商品详细信息,并可以将商品加入购物车。
  • 购物车页展示购物车中的商品,并可以提交订单。
  • 订单页展示订单信息。

5. 注意事项

  1. 权限管理:在使用微信授权登录时,需要确保用户授权信息的安全性。
  2. 网络请求:在实际项目中,需要确保网络请求的稳定性和安全性,建议使用 HTTPS 协议。
  3. 状态管理:使用 Vuex 管理全局状态时,需要注意状态的一致性和同步性。
  4. 路由管理:使用 Vue Router 管理页面路由时,需要确保路由跳转的顺畅性和用户体验。
  5. UI设计:选择合适的 UI 库(如 uView UI)可以大大提高开发效率和界面美观度。

6. 总结

通过本篇博客,我们详细介绍了如何使用 uni-app 开发微信小程序,并通过一个简单的示例展示了整个开发过程。uni-app 的优势在于它可以一次开发多端部署,极大地提高了开发效率。希望这篇博客能帮助你在实际项目中更好地应用 uni-app。

如果你有任何疑问或建议,请随时留言交流。祝你开发顺利!

目录
相关文章
预约按摩小程序开发,为什么很多上门按摩平台根本招聘不到优秀技师?
上门按摩平台面临招不到优秀技师的问题,主要原因是平台众多,技师选择多样。为解决此问题,平台可引入技师等级制度,根据订单数量和好评率划分高、低等级技师。高等级技师可享受70%-90%的高提成及首页推荐,这不仅能激励技师的积极性,还能帮助平台筛选出优质技师,提升服务质量和口碑,形成良性循环。
|
14天前
|
小程序 Android开发
|
3天前
|
小程序 云计算 Android开发
发者社区 云计算 文章 正文 小程序开发与公众号用户关联推送消息(九)
发者社区 云计算 文章 正文 小程序开发与公众号用户关联推送消息(九)
16 3
|
9天前
|
小程序
|
10天前
|
小程序 数据安全/隐私保护
|
9天前
|
小程序
|
15天前
|
人工智能 小程序
【一步步开发AI运动小程序】五、帧图像人体识别
随着AI技术的发展,阿里体育等公司推出的AI运动APP,如“乐动力”和“天天跳绳”,使云上运动会、线上健身等概念广受欢迎。本文将引导您从零开始开发一个AI运动小程序,使用“云智AI运动识别小程序插件”。文章分为四部分:初始化人体识别功能、调用人体识别功能、人体识别结果处理以及识别结果旋转矫正。下篇将继续介绍人体骨骼图绘制。
|
13天前
|
机器人
布谷直播App系统源码开发之后台管理功能详解
直播系统开发搭建管理后台功能详解!
|
13天前
|
小程序