跳转至

移动端开发规范 (Mobile App Development)

定位:uni-app x 跨平台移动应用开发标准,一套代码多端发布,确保高性能、可维护。


技术选型

层级 技术栈 版本要求 选型理由
框架 uni-app x ≥ 4.0 基于 Vue 3、原生渲染、一套代码多端发布
开发语言 uts (Uni Type Script) - 类型安全、编译到原生、性能接近原生
UI 组件 uni-ui / uView 最新 官方/社区组件库,跨端兼容
状态管理 Pinia ≥ 2.0 Vue 3 官方推荐、TS 支持好
网络请求 uni.request 封装 - 统一请求/响应处理
开发工具 HBuilderX 最新 官方 IDE、调试方便

发布平台

平台 说明
Android 原生 APK,性能接近原生
iOS 原生 IPA,需 Mac 环境打包
微信小程序 编译为小程序代码
H5 Web 应用

核心优势:uni-app x 使用 uts 语言,编译为原生代码(Kotlin/Swift),性能远超传统 uni-app。


项目结构

MyApp/
├── pages/                  # 页面目录
│   ├── index/              # 首页
│   │   └── index.uvue
│   ├── user/               # 用户模块
│   │   └── profile.uvue
│   └── ...
├── pagesA/                 # 分包 A
├── pagesB/                 # 分包 B
├── components/             # 公共组件
│   ├── base/               # 基础组件
│   └── business/           # 业务组件
├── composables/            # 组合式函数
│   └── useAuth.uts
├── stores/                 # Pinia 状态管理
│   └── user.uts
├── api/                    # API 接口
│   ├── request.uts         # 请求封装
│   └── modules/            # 按模块拆分
├── utils/                  # 工具函数
├── static/                 # 静态资源
├── uni_modules/            # uni 插件
├── App.uvue                # 应用入口
├── main.uts                # 入口文件
├── pages.json              # 页面配置
├── manifest.json           # 应用配置
└── uni.scss                # 全局样式变量

核心组件

组件 用途 说明
view 布局容器 类似 div
text 文本显示 所有文本必须包裹
scroll-view 滚动容器 可横向/纵向滚动
list 长列表 大列表必须使用,高性能渲染
swiper 轮播图 滑动切换容器
image 图片 支持懒加载
input 输入框 表单输入
button 按钮 跨端样式统一

命名规范

类型 规范 示例
页面目录 小写 + 连字符 user-profile/
组件文件 小写 + 连字符 user-card.uvue
变量/函数 camelCase getUserInfo
常量 UPPER_SNAKE API_BASE_URL
类型/接口 PascalCase UserInfo
组合式函数 use 前缀 useAuth

页面配置 (pages.json)

{
  "pages": [
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "首页"
      }
    }
  ],
  "subPackages": [
    {
      "root": "pagesA",
      "pages": [
        {
          "path": "list/list",
          "style": { "navigationBarTitleText": "列表" }
        }
      ]
    }
  ],
  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarBackgroundColor": "#ffffff"
  }
}

样式规范

rpx 响应式单位

/* 使用 rpx 适配不同屏幕 */
.container {
  width: 750rpx;      /* 满屏宽度(设计稿基准 750) */
  padding: 32rpx;
  font-size: 28rpx;
}

全局样式变量 (uni.scss)

/* uni.scss */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;

$uni-spacing-sm: 16rpx;
$uni-spacing-md: 32rpx;
$uni-spacing-lg: 48rpx;

平台条件编译

/* #ifdef APP-ANDROID */
.container { padding-top: 44px; }
/* #endif */

/* #ifdef APP-IOS */
.container { padding-top: 50px; }
/* #endif */

/* #ifdef MP-WEIXIN */
.container { padding-top: 0; }
/* #endif */

状态管理 (Pinia)

定义 Store

// stores/user.uts
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', () => {
  const token = ref<string>('')
  const userInfo = ref<UserInfo | null>(null)

  const isLoggedIn = computed(() => !!token.value)

  function setToken(newToken: string) {
    token.value = newToken
  }

  function logout() {
    token.value = ''
    userInfo.value = null
  }

  return { token, userInfo, isLoggedIn, setToken, logout }
})

使用 Store

<script setup lang="uts">
import { useUserStore } from '@/stores/user'

const userStore = useUserStore()
const { userInfo, isLoggedIn } = storeToRefs(userStore)
</script>

网络请求封装

请求工具

// api/request.uts
interface RequestOptions {
  url: string
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
  data?: any
  showLoading?: boolean
}

interface ApiResponse<T> {
  code: number
  message: string
  data: T
}

export async function request<T>(options: RequestOptions): Promise<ApiResponse<T>> {
  const { url, method = 'GET', data, showLoading = true } = options

  if (showLoading) {
    uni.showLoading({ title: '加载中', mask: true })
  }

  return new Promise((resolve, reject) => {
    uni.request({
      url: API_BASE_URL + url,
      method,
      data,
      success: (res) => {
        resolve(res.data as ApiResponse<T>)
      },
      fail: (err) => {
        uni.showToast({ title: '网络错误', icon: 'none' })
        reject(err)
      },
      complete: () => {
        if (showLoading) uni.hideLoading()
      }
    })
  })
}

API 模块化

// api/modules/user.uts
import { request } from '../request'

export const userApi = {
  getUser: (id: number) => request<UserInfo>({
    url: `/user/${id}`
  }),

  updateUser: (data: UserUpdate) => request<UserInfo>({
    url: '/user',
    method: 'PUT',
    data
  })
}

性能优化

长列表优化

<template>
  <!-- 使用 list 组件,虚拟列表渲染 -->
  <list class="list" :enable-back-to-top="true">
    <cell v-for="item in list" :key="item.id">
      <item-card :item="item" />
    </cell>
  </list>
</template>

图片懒加载

<image :src="imageUrl" mode="aspectFill" lazy-load />

分包预加载

// pages.json
{
  "preloadRule": {
    "pages/index/index": {
      "network": "all",
      "packages": ["pagesA"]
    }
  }
}

条件编译

平台判断

// #ifdef APP-ANDROID
console.log('Android 平台')
// #endif

// #ifdef APP-IOS
console.log('iOS 平台')
// #endif

// #ifdef MP-WEIXIN
console.log('微信小程序')
// #endif

// #ifdef H5
console.log('H5 平台')
// #endif

平台差异化代码

<template>
  <view>
    <!-- #ifdef APP-ANDROID -->
    <text>Android 专属功能</text>
    <!-- #endif -->
  </view>
</template>

原生插件开发

Android 原生插件 (Kotlin)

// uni_modules/my-plugin/android/src/main/kotlin/MyModule.kt
class MyModule : UTSComponent() {
    @UniJSMethod
    fun showToast(message: String) {
        // 原生实现
    }
}

iOS 原生插件 (Swift)

// uni_modules/my-plugin/ios/Sources/MyModule.swift
@objc(MyModule)
class MyModule: NSObject {
  @objc func showToast(_ message: String) {
    // 原生实现
  }
}

开发环境要求

项目 要求
HBuilderX 最新正式版
Node.js ≥ 18(CLI 模式需要)
Android Studio 最新版(Android 开发)
Xcode ≥ 15(iOS 开发,仅 macOS)
内存 最低 8GB,推荐 16GB

常见陷阱

问题 原因 解法
样式不生效 使用了不支持的 CSS 查阅 uni-app x 支持的样式列表
列表卡顿 使用 v-for 渲染大列表 使用 list + cell 组件
图片不显示 路径错误或未配置域名 检查路径、配置合法域名
编译报错 uts 语法问题 检查类型定义,使用严格类型
平台差异 未做条件编译 使用 #ifdef 处理差异

调试技巧

场景 方法
App 端 HBuilderX 真机调试
小程序 微信开发者工具预览
H5 浏览器控制台
网络请求 控制台 Network 面板

沉淀协议

场景 行动
组件复用 ≥ 2 次 提取到 components/base/
API 调用模式重复 ≥ 3 次 封装到 api/modules/
状态逻辑重复 ≥ 2 次 提取到 stores/composables/
平台差异处理固化 更新本文档条件编译章节