一、企业级Uniapp架构设计
本教程将基于Uniapp构建一个适配微信小程序、H5和App的企业级应用,涵盖从开发到上线的完整流程。
技术架构:
- 核心框架:Uniapp 3.8 + Vue2
- UI组件:uView UI 3.0 + 自定义主题
- 状态管理:Vuex模块化
- 网络请求:二次封装uni.request
- 多端适配:条件编译 + 平台检测
核心功能模块:
- 统一身份认证系统
- 高性能列表渲染方案
- 原生功能混合开发
- 多主题切换方案
- 应用性能监控体系
- 自动化构建部署
二、项目工程化配置
1. 高级项目初始化
# 使用Vue CLI创建项目
vue create -p dcloudio/uni-preset-vue enterprise-app
# 安装核心依赖
cd enterprise-app
npm install uview-ui @dcloudio/uni-ui sass-loader node-sass
# 配置vue.config.js
module.exports = {
transpileDependencies: ['uview-ui'],
configureWebpack: {
optimization: {
splitChunks: {
chunks: 'all',
maxSize: 244 * 1024
}
}
}
}
2. 多环境配置方案
// config/env.js
const env = process.env.NODE_ENV || 'development'
const configMap = {
development: {
baseUrl: 'https://dev.api.com',
appId: 'dev_123456'
},
production: {
baseUrl: 'https://api.com',
appId: 'prod_123456'
}
}
export default configMap[env]
// package.json
"scripts": {
"build:dev": "cross-env NODE_ENV=development uni-build",
"build:prod": "cross-env NODE_ENV=production uni-build"
}
三、核心功能实现
1. 高性能列表渲染
<template>
<view class="list-container">
<!-- 虚拟列表组件 -->
<uni-list
:total="total"
:item-height="itemHeight"
@render="renderItem">
<template v-slot:default="{ index }">
<list-item :data="visibleData[index]" />
</template>
</uni-list>
<!-- 下拉刷新 -->
<uni-pull-refresh @refresh="handleRefresh" />
<!-- 上拉加载 -->
<uni-load-more
:status="loadStatus"
@loadmore="handleLoadMore" />
</view>
</template>
<script>
export default {
data() {
return {
total: 0,
itemHeight: 120,
visibleData: [],
loadStatus: 'more'
}
},
methods: {
async loadData(page) {
try {
const res = await this.$api.getList({
page,
size: 20
})
this.total = res.total
this.visibleData = page === 1 ?
res.list : [...this.visibleData, ...res.list]
this.loadStatus = res.list.length ? 'more' : 'noMore'
} catch (e) {
this.loadStatus = 'error'
}
},
renderItem({ start, end }) {
// 计算可视区域数据
},
handleRefresh() {
this.loadData(1)
},
handleLoadMore() {
if (this.loadStatus === 'more') {
this.loadData(this.currentPage + 1)
}
}
}
}
</script>
2. 统一身份认证
// utils/auth.js
class Auth {
static async login(credentials) {
// 多端登录适配
// #ifdef MP-WEIXIN
const { code } = await this.wxLogin()
return uni.request({
url: '/auth/wx',
data: { code, ...credentials }
})
// #endif
// #ifdef H5 || APP-PLUS
return uni.request({
url: '/auth/login',
method: 'POST',
data: credentials
})
// #endif
}
static async wxLogin() {
return new Promise((resolve, reject) => {
uni.login({
success: resolve,
fail: reject
})
})
}
static setToken(token) {
uni.setStorageSync('token', token)
// 请求拦截器自动添加
}
static checkAuth() {
return !!uni.getStorageSync('token')
}
}
export default Auth
四、多端适配方案
1. 平台差异化组件
// components/PlatformButton/index.vue
<template>
<!-- 微信小程序 -->
<!-- #ifdef MP-WEIXIN -->
<button
class="wx-button"
:style="styles"
@click="$emit('click')">
<slot></slot>
</button>
<!-- #endif -->
<!-- H5/App -->
<!-- #ifdef H5 || APP-PLUS -->
<view
class="native-button"
:style="styles"
@click="$emit('click')">
<slot></slot>
</view>
<!-- #endif -->
</template>
<script>
export default {
props: {
type: {
type: String,
default: 'default'
}
},
computed: {
styles() {
const styleMap = {
primary: {
backgroundColor: '#2979ff',
color: '#fff'
},
default: {
backgroundColor: '#f8f8f8',
color: '#333'
}
}
return styleMap[this.type]
}
}
}
</script>
2. 统一API封装
// utils/request.js
const request = (options) => {
// 多端统一配置
const config = {
baseURL: process.env.baseUrl,
header: {
'X-Platform': process.env.VUE_APP_PLATFORM
}
}
// 请求拦截
const token = uni.getStorageSync('token')
if (token) {
config.header.Authorization = `Bearer ${token}`
}
return new Promise((resolve, reject) => {
uni.request({
...config,
...options,
success: (res) => {
if (res.statusCode === 401) {
// 跳转登录
}
resolve(res.data)
},
fail: reject
})
})
}
// 挂载到Vue原型
Vue.prototype.$http = request
五、性能优化体系
1. 图片优化方案
// components/SmartImage.vue
<template>
<view>
<!-- 懒加载 -->
<image
v-if="showImage"
:src="realSrc"
:mode="mode"
@load="handleLoad"
@error="handleError" />
<!-- 占位图 -->
<view v-else class="placeholder" />
</view>
</template>
<script>
export default {
props: {
src: String,
mode: {
type: String,
default: 'scaleToFill'
},
lazy: {
type: Boolean,
default: true
}
},
data() {
return {
showImage: false,
realSrc: ''
}
},
mounted() {
if (!this.lazy) {
this.loadImage()
} else {
this.initObserver()
}
},
methods: {
initObserver() {
const observer = uni.createIntersectionObserver(this)
observer.relativeToViewport()
.observe('.placeholder', (res) => {
if (res.intersectionRatio > 0) {
this.loadImage()
observer.disconnect()
}
})
},
loadImage() {
// 根据网络环境加载不同质量图片
const isWifi = uni.getNetworkType().networkType === 'wifi'
this.realSrc = isWifi ? this.src : `${this.src}?quality=50`
this.showImage = true
},
handleLoad() {
this.$emit('load')
},
handleError() {
this.realSrc = '/static/error.png'
}
}
}
</script>
2. 分包预加载策略
// pages.json
{
"pages": [
{
"path": "pages/index/index",
"style": { ... }
}
],
"subPackages": [
{
"root": "pages/user",
"pages": [
{
"path": "center/index",
"style": { ... }
}
]
}
],
"preloadRule": {
"pages/index/index": {
"network": "wifi",
"packages": ["pages/user"]
}
}
}
六、原生功能扩展
1. 原生插件集成
// utils/native.js
export const scanCode = () => {
return new Promise((resolve, reject) => {
// #ifdef APP-PLUS
const scanner = uni.requireNativePlugin('NativeScanner')
scanner.scan({
success: resolve,
fail: reject
})
// #endif
// #ifdef MP-WEIXIN
uni.scanCode({
success: (res) => resolve(res.result),
fail: reject
})
// #endif
// #ifdef H5
reject(new Error('H5不支持扫码'))
// #endif
})
}
2. 多主题切换方案
// styles/theme.scss
$themes: (
light: (
primary-color: #409EFF,
background-color: #f5f7fa
),
dark: (
primary-color: #79bbff,
background-color: #1f1f1f
)
);
// mixins/theme.scss
@mixin themeify {
@each $theme-name, $theme-map in $themes {
[data-theme="#{$theme-name}"] & {
$theme-map: () !global;
@each $key, $value in $theme-map {
$theme-map: map-merge($theme-map, ($key: $value)) !global;
}
@content;
$theme-map: null !global;
}
}
}
// 在组件中使用
.container {
@include themeify {
background-color: themed('background-color');
}
}
七、构建与部署
1. 自动化构建脚本
#!/bin/bash
# 构建不同平台
platforms=("h5" "mp-weixin" "app-plus")
for platform in "${platforms[@]}"
do
echo "Building for $platform"
cross-env NODE_ENV=production UNI_PLATFORM=$platform vue-cli-service uni-build
# 处理特殊平台配置
if [ "$platform" == "app-plus" ]; then
# 处理原生APP配置
cp -r ./nativeResources ./dist/build/app-plus/
fi
done
echo "Build completed"
2. CI/CD集成
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install dependencies
run: npm install
- name: Build for WeChat
run: |
npm run build:mp-weixin
zip -r weapp.zip ./dist/build/mp-weixin
- name: Deploy to WeChat
uses: wshihadeh/wechat-miniprogram-action@v1
with:
appid: ${{ secrets.WX_APPID }}
version: ${{ github.sha }}
desc: 'Auto deploy from CI'
project-path: ./dist/build/mp-weixin
private-key: ${{ secrets.WX_PRIVATE_KEY }}
八、总结与展望
本教程完整实现了企业级Uniapp应用的开发:
- 构建了工程化项目架构
- 实现了高性能核心功能
- 完善了多端适配方案
- 优化了应用性能表现
- 建立了自动化部署流程
未来扩展方向:
- 微前端架构集成
- Flutter混合开发
- 小程序云开发深度整合
- 全链路监控系统