UniApp跨平台开发实战:从零构建企业级电商应用 | UniApp教程

2025-08-28 0 278

UniApp框架概述与优势

UniApp是一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/快手/钉钉/淘宝)、快应用等多个平台。它具有开发效率高、学习成本低、生态丰富等显著优势。

环境搭建与项目创建

首先需要安装HBuilderX IDE,这是UniApp官方推荐的开发工具。

安装与创建项目


# 通过HBuilderX可视化创建
1. 打开HBuilderX → 文件 → 新建 → 项目
2. 选择uni-app项目类型
3. 输入项目名称,选择模板(推荐使用默认模板)
4. 点击创建

# 或者通过CLI方式创建(需先安装vue-cli)
npm install -g @vue/cli
vue create -p dcloudio/uni-preset-vue my-project
        

项目目录结构


my-project/
├── pages/                 # 页面文件目录
│   ├── index/
│   │   ├── index.vue      # 首页页面
│   │   └── index.json     # 页面配置文件
│   └── ...
├── static/                # 静态资源目录
├── components/            # 自定义组件目录
├── uni_modules/           # uni模块目录
├── App.vue                # 应用入口文件
├── main.js                # 应用入口js
├── manifest.json          # 应用配置文件
├── pages.json             # 页面路由配置文件
└── uni.scss               # 全局scss变量文件
        

核心配置文件详解

pages.json – 全局页面配置


{
    "pages": [
        {
            "path": "pages/index/index",
            "style": {
                "navigationBarTitleText": "首页",
                "enablePullDownRefresh": true,
                "backgroundColor": "#F8F8F8"
            }
        },
        {
            "path": "pages/product/list",
            "style": {
                "navigationBarTitleText": "商品列表",
                "enablePullDownRefresh": false
            }
        }
    ],
    "globalStyle": {
        "navigationBarTextStyle": "black",
        "navigationBarTitleText": "uni-app",
        "navigationBarBackgroundColor": "#FFFFFF",
        "backgroundColor": "#FFFFFF",
        "app-plus": {
            "titleView": false
        }
    },
    "tabBar": {
        "color": "#7A7E83",
        "selectedColor": "#007AFF",
        "backgroundColor": "#FFFFFF",
        "list": [
            {
                "pagePath": "pages/index/index",
                "iconPath": "static/tabbar/home.png",
                "selectedIconPath": "static/tabbar/home_active.png",
                "text": "首页"
            },
            {
                "pagePath": "pages/cart/cart",
                "iconPath": "static/tabbar/cart.png",
                "selectedIconPath": "static/tabbar/cart_active.png",
                "text": "购物车"
            }
        ]
    }
}
        

manifest.json – 应用配置


{
    "name": "我的电商应用",
    "appid": "__UNI__XXXXXX",
    "description": "一个基于UniApp开发的电商应用",
    "versionName": "1.0.0",
    "versionCode": "100",
    "transformPx": false,
    "app-plus": {
        "usingComponents": true,
        "nvueStyleCompiler": "uni-app",
        "compilerVersion": 3,
        "splashscreen": {
            "alwaysShowBeforeRender": true,
            "waiting": true,
            "autoclose": true,
            "delay": 0
        }
    },
    "mp-weixin": {
        "appid": "wxxxxxxxxxxxxxx",
        "setting": {
            "urlCheck": false
        },
        "usingComponents": true
    }
}
        

实战:电商应用首页开发

首页Vue组件结构


<template>
    <view class="container">
        <!-- 搜索栏 -->
        <view class="search-bar">
            <view class="search-box" @click="navigateToSearch">
                <uni-icons type="search" size="18"></uni-icons>
                <text class="placeholder">搜索商品</text>
            </view>
        </view>
        
        <!-- 轮播图 -->
        <swiper class="swiper" circular indicator-dots autoplay interval="3000">
            <swiper-item v-for="(item, index) in bannerList" :key="index">
                <image :src="item.image" mode="aspectFill" @click="navigateTo(item.url)"></image>
            </swiper-item>
        </swiper>
        
        <!-- 分类导航 -->
        <view class="category-nav">
            <view 
                class="nav-item" 
                v-for="(item, index) in categoryList" 
                :key="index"
                @click="navigateToCategory(item.id)"
            >
                <image :src="item.icon"></image>
                <text>{{ item.name }}</text>
            </view>
        </view>
        
        <!-- 商品列表 -->
        <view class="product-section">
            <view class="section-title">
                <text>热门推荐</text>
                <text class="more" @click="navigateToProductList">查看更多 ></text>
            </view>
            
            <view class="product-list">
                <view 
                    class="product-item" 
                    v-for="(product, index) in productList" 
                    :key="index"
                    @click="navigateToProductDetail(product.id)"
                >
                    <image class="product-image" :src="product.image" mode="aspectFill"></image>
                    <view class="product-info">
                        <text class="product-name">{{ product.name }}</text>
                        <text class="product-desc">{{ product.description }}</text>
                        <view class="product-price">
                            <text class="current-price">¥{{ product.price }}</text>
                            <text class="original-price" v-if="product.originalPrice">¥{{ product.originalPrice }}</text>
                        </view>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            bannerList: [
                { image: '/static/banner/1.jpg', url: '/pages/product/detail?id=1' },
                { image: '/static/banner/2.jpg', url: '/pages/product/detail?id=2' },
                { image: '/static/banner/3.jpg', url: '/pages/product/detail?id=3' }
            ],
            categoryList: [
                { id: 1, name: '手机数码', icon: '/static/category/phone.png' },
                { id: 2, name: '家用电器', icon: '/static/category/appliance.png' },
                { id: 3, name: '服装鞋帽', icon: '/static/category/clothes.png' },
                { id: 4, name: '美妆个护', icon: '/static/category/beauty.png' },
                { id: 5, name: '生鲜食品', icon: '/static/category/food.png' }
            ],
            productList: [
                {
                    id: 1,
                    name: '高端智能手机',
                    description: '超清全面屏,超长续航',
                    price: 3999,
                    originalPrice: 4999,
                    image: '/static/product/1.jpg'
                },
                {
                    id: 2,
                    name: '无线蓝牙耳机',
                    description: '主动降噪,高清音质',
                    price: 699,
                    originalPrice: 899,
                    image: '/static/product/2.jpg'
                }
            ]
        }
    },
    methods: {
        navigateToSearch() {
            uni.navigateTo({
                url: '/pages/search/search'
            })
        },
        navigateTo(url) {
            uni.navigateTo({
                url: url
            })
        },
        navigateToCategory(categoryId) {
            uni.navigateTo({
                url: `/pages/product/list?categoryId=${categoryId}`
            })
        },
        navigateToProductList() {
            uni.navigateTo({
                url: '/pages/product/list'
            })
        },
        navigateToProductDetail(productId) {
            uni.navigateTo({
                url: `/pages/product/detail?id=${productId}`
            })
        }
    }
}
</script>
        

状态管理与数据请求

使用Vuex进行状态管理


// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        userInfo: null,
        cartCount: 0,
        token: uni.getStorageSync('token') || ''
    },
    mutations: {
        SET_USER_INFO(state, userInfo) {
            state.userInfo = userInfo
        },
        SET_CART_COUNT(state, count) {
            state.cartCount = count
        },
        SET_TOKEN(state, token) {
            state.token = token
            uni.setStorageSync('token', token)
        },
        CLEAR_USER_DATA(state) {
            state.userInfo = null
            state.token = ''
            state.cartCount = 0
            uni.removeStorageSync('token')
        }
    },
    actions: {
        // 登录动作
        async login({ commit }, loginData) {
            try {
                const res = await uni.request({
                    url: '/api/user/login',
                    method: 'POST',
                    data: loginData
                })
                
                if (res.data.code === 200) {
                    commit('SET_TOKEN', res.data.data.token)
                    commit('SET_USER_INFO', res.data.data.userInfo)
                    return Promise.resolve(res.data)
                } else {
                    return Promise.reject(res.data)
                }
            } catch (error) {
                return Promise.reject(error)
            }
        },
        
        // 获取购物车数量
        async getCartCount({ commit }) {
            try {
                const res = await uni.request({
                    url: '/api/cart/count',
                    method: 'GET'
                })
                
                if (res.data.code === 200) {
                    commit('SET_CART_COUNT', res.data.data.count)
                }
            } catch (error) {
                console.error('获取购物车数量失败', error)
            }
        }
    }
})

export default store
        

封装网络请求


// utils/request.js
const BASE_URL = 'https://api.example.com'

const request = (options) => {
    return new Promise((resolve, reject) => {
        const { url, method = 'GET', data = {}, header = {} } = options
        
        // 添加token到请求头
        const token = uni.getStorageSync('token')
        if (token) {
            header['Authorization'] = 'Bearer ' + token
        }
        
        uni.request({
            url: BASE_URL + url,
            method,
            data,
            header,
            success: (res) => {
                if (res.statusCode === 200) {
                    resolve(res.data)
                } else if (res.statusCode === 401) {
                    // token过期,跳转到登录页
                    uni.navigateTo({
                        url: '/pages/login/login'
                    })
                    reject(res.data)
                } else {
                    reject(res.data)
                }
            },
            fail: (error) => {
                reject(error)
            }
        })
    })
}

// 封装常用请求方法
export const get = (url, data = {}) => {
    return request({ url, method: 'GET', data })
}

export const post = (url, data = {}) => {
    return request({ url, method: 'POST', data })
}

export const put = (url, data = {}) => {
    return request({ url, method: 'PUT', data })
}

export const del = (url, data = {}) => {
    return request({ url, method: 'DELETE', data })
}

export default request
        

常用UI组件与自定义组件

使用uni-ui组件库


// 安装uni-ui
npm install @dcloudio/uni-ui

// 在页面中使用
<template>
    <view>
        <uni-nav-bar title="商品详情" left-icon="back" @clickLeft="goBack"></uni-nav-bar>
        
        <uni-swipe-action>
            <uni-swipe-action-item :options="options" @click="onSwipeClick">
                <view class="cart-item">
                    <image class="product-image" :src="product.image"></image>
                    <view class="product-info">
                        <text class="product-name">{{ product.name }}</text>
                        <text class="product-price">¥{{ product.price }}</text>
                    </view>
                </view>
            </uni-swipe-action-item>
        </uni-swipe-action>
        
        <uni-load-more :status="loadStatus"></uni-load-more>
    </view>
</template>

<script>
import uniNavBar from '@dcloudio/uni-ui/lib/uni-nav-bar/uni-nav-bar.vue'
import uniSwipeAction from '@dcloudio/uni-ui/lib/uni-swipe-action/uni-swipe-action.vue'
import uniLoadMore from '@dcloudio/uni-ui/lib/uni-load-more/uni-load-more.vue'

export default {
    components: {
        uniNavBar,
        uniSwipeAction,
        uniLoadMore
    },
    data() {
        return {
            options: [
                {
                    text: '删除',
                    style: {
                        backgroundColor: '#dd524d'
                    }
                }
            ],
            loadStatus: 'more'
        }
    },
    methods: {
        goBack() {
            uni.navigateBack()
        },
        onSwipeClick(e) {
            if (e.index === 0) {
                this.deleteCartItem()
            }
        }
    }
}
</script>
        

自定义弹窗组件


// components/custom-modal.vue
<template>
    <view class="modal-mask" v-if="visible" @click="close">
        <view class="modal-container" @click.stop>
            <view class="modal-header">
                <text class="modal-title">{{ title }}</text>
                <uni-icons 
                    type="close" 
                    size="24" 
                    class="close-icon" 
                    @click="close"
                ></uni-icons>
            </view>
            <view class="modal-content">
                <slot></slot>
            </view>
            <view class="modal-footer" v-if="showFooter">
                <button class="btn-cancel" @click="cancel">取消</button>
                <button class="btn-confirm" @click="confirm">确认</button>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    name: 'CustomModal',
    props: {
        visible: {
            type: Boolean,
            default: false
        },
        title: {
            type: String,
            default: '提示'
        },
        showFooter: {
            type: Boolean,
            default: true
        }
    },
    methods: {
        close() {
            this.$emit('update:visible', false)
            this.$emit('close')
        },
        cancel() {
            this.$emit('cancel')
            this.close()
        },
        confirm() {
            this.$emit('confirm')
        }
    }
}
</script>
        

平台差异化处理与打包发布

条件编译处理平台差异


// 平台条件编译
<template>
    <view>
        <!-- #ifdef MP-WEIXIN -->
        <button open-type="getUserInfo" @getuserinfo="getUserInfo">微信登录</button>
        <!-- #endif -->
        
        <!-- #ifdef APP-PLUS -->
        <button @click="appLogin">APP登录</button>
        <!-- #endif -->
        
        <!-- #ifdef H5 -->
        <button @click="h5Login">H5登录</button>
        <!-- #endif -->
    </view>
</template>

// JS中的条件编译
onLoad() {
    // #ifdef MP-WEIXIN
    console.log('微信小程序平台')
    // #endif
    
    // #ifdef APP-PLUS
    console.log('APP平台')
    // #endif
}

// 样式中的条件编译
.example {
    color: #000000;
    /* #ifdef MP-WEIXIN */
    padding: 10rpx;
    /* #endif */
    
    /* #ifdef APP-PLUS */
    padding: 20rpx;
    /* #endif */
}
        

应用打包与发布


# 微信小程序发布流程
1. 在HBuilderX中选择"发行" → "小程序-微信"
2. 输入小程序名称和AppID
3. 点击发行,生成微信小程序代码包
4. 使用微信开发者工具打开生成的代码包
5. 在微信开发者工具中上传代码
6. 登录微信小程序后台,提交审核并发布

# APP打包流程
1. 在HBuilderX中选择"发行" → "原生App-云打包"
2. 选择打包平台(iOS/Android)
3. 配置证书和签名(Android使用自有证书,iOS需要苹果开发者账号)
4. 选择模块和权限配置
5. 点击打包,等待云端打包完成
6. 下载打包好的安装包进行分发

# H5发布流程
1. 在HBuilderX中选择"发行" → "网站-H5手机版"
2. 配置网站标题和域名
3. 点击发行,生成H5资源文件
4. 将生成的文件部署到服务器
        

性能优化与最佳实践

UniApp性能优化策略

  • 图片优化:使用合适的图片格式和尺寸,懒加载图片
  • 数据缓存:合理使用本地存储和Vuex状态管理
  • 组件优化:使用v-if和v-show合理控制组件渲染
  • 减少setData:避免频繁调用setData,合并数据更新
  • 分包加载:使用分包机制减少主包体积
  • 按需引入:组件和API按需引入,减少打包体积

分包配置示例


// pages.json
{
    "pages": [
        {
            "path": "pages/index/index",
            "style": { ... }
        }
    ],
    "subPackages": [
        {
            "root": "pagesA",
            "pages": [
                {
                    "path": "product/list",
                    "style": { ... }
                },
                {
                    "path": "product/detail",
                    "style": { ... }
                }
            ]
        },
        {
            "root": "pagesB",
            "pages": [
                {
                    "path": "user/center",
                    "style": { ... }
                },
                {
                    "path": "user/settings",
                    "style": { ... }
                }
            ]
        }
    ],
    "preloadRule": {
        "pages/index/index": {
            "network": "all",
            "packages": ["pagesA"]
        }
    }
}
        

总结

通过本教程,我们全面学习了UniApp的开发流程和核心技术:

  • UniApp环境搭建和项目结构
  • 核心配置文件和页面路由管理
  • Vue.js在UniApp中的应用和状态管理
  • 网络请求封装和API调用
  • UI组件使用和自定义组件开发
  • 多平台差异化处理和条件编译
  • 应用打包发布和性能优化策略

UniApp作为跨平台开发框架,极大提高了开发效率,让开发者能够用一套代码构建多端应用。掌握这些技术将使你能够快速开发高质量的商业级应用。

UniApp跨平台开发实战:从零构建企业级电商应用 | UniApp教程
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 uniapp UniApp跨平台开发实战:从零构建企业级电商应用 | UniApp教程 https://www.taomawang.com/web/uniapp/994.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务