在跨端开发成为主流的今天,Uniapp + Vue3 + PHP 的组合已经成为中小团队交付小程序项目的“工业级标配”。一套代码,编译到微信小程序、H5、App,后端用 PHP 承接业务逻辑与数据,既能满足快速上线,又能保证后期可维护。本文将以一份标准的 Uniapp 小程序源码 为核心,系统性拆解其工程结构、Vue3 组合式 API 实战、微信小程序适配要点,以及 PHP 后端如何设计一套“多端通用”的接口体系。


源码及演示:y.wxlbyx.icu

一、为什么选择 Uniapp + Vue3 + PHP 这套技术栈

很多团队在小程序起步阶段会在“原生开发”和“跨端框架”之间犹豫,而 Uniapp 在以下几个维度上非常契合商业项目:
在这里插入图片描述

  1. 多端复用:同一套 pages/components/store/,一键编译到微信小程序、支付宝小程序、H5、Android/iOS App,极大降低维护成本。
  2. Vue3 的开发体验<script setup>、Composition API、响应式系统(ref/reactive),让复杂业务的状态管理更清晰,组件复用性更强。
  3. PHP 后端的普适性:LAMP/LNMP 环境成熟,Laravel / ThinkPHP / Webman 等框架生态完善,中小项目部署成本低,招人成本也低。
  4. 源码交付友好:Uniapp 源码结构清晰,PHP 接口分层明确,非常适合作为“成品源码”进行二次销售、二开或 SaaS 化改造。

因此,一套标注为 “Uniapp小程序源码 - Vue3+PHP多端通用” 的工程,本质上应该是一个“开箱即用、可跨端、可私有化部署”的商业级解决方案。


二、Uniapp 小程序源码的标准目录结构(Vue3 版)

在这里插入图片描述

拿到一份规范的 Uniapp 源码,根目录通常呈现如下结构(以微信小程序为主要编译目标):

/root
├── src/                        # 源码主目录(uniapp 标准)
│   ├── pages/                  # 业务页面
│   │   ├── index/              # 首页
│   │   ├── user/               # 用户中心
│   │   ├── goods/              # 商品/内容模块
│   │   └── order/              # 订单流程
│   ├── components/             # 公共组件(Vue3 SFC)
│   │   ├── base/               # 基础组件:按钮、卡片、弹窗
│   │   └── biz/                # 业务组件:商品卡片、地址选择器等
│   ├── composables/            # 组合式函数(hooks)
│   │   ├── useUser.ts          # 用户信息管理
│   │   ├── useRequest.ts       # 请求封装
│   │   └── usePayment.ts       # 支付逻辑
│   ├── store/                  # Pinia 状态管理
│   │   ├── user.ts
│   │   ├── cart.ts
│   │   └── index.ts
│   ├── utils/                  # 工具方法
│   │   ├── request.ts          # uni.request 封装
│   │   ├── auth.ts             # token / openid 处理
│   │   └── env.ts              # 多端环境变量
│   ├── static/                 # 静态资源
│   │   ├── images/
│   │   └── icons/
│   ├── manifest.json           # uniapp 应用配置
│   ├── pages.json              # 页面路由 & 窗口样式
│   ├── uni.scss                # 全局样式变量
│   └── App.vue                 # 应用入口(生命周期)
│
├── server-php/                 # PHP 后端工程
│   ├── app/
│   │   ├── Controllers/
│   │   ├── Models/
│   │   ├── Middleware/
│   │   └── Routes/
│   ├── config/
│   ├── public/index.php
│   └── .env
└── package.json

源码验收标准

  • pages.json 中是否配置了 usingComponents(原生小程序组件兼容)
  • 是否存在 composables/ 目录(Vue3 项目的重要标志)
  • PHP 端是否有统一的 BaseController 与返回格式

三、Vue3 在 Uniapp 中的工程化实践

在这里插入图片描述

3.1 <script setup> 成为主流

在 Uniapp 的 Vue3 工程中,<script setup> 基本替代了 Vue2 的 export default。以一个简单的商品列表页为例:

<!-- pages/goods/list.vue -->
<template>
  <view class="goods-list">
    <GoodsCard v-for="item in list" :key="item.id" :data="item" />
    <uni-load-more :status="loadStatus" />
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { onReachBottom } from '@dcloudio/uni-app'
import { getGoodsList } from '@/api/goods'
import GoodsCard from '@/components/biz/GoodsCard.vue'

const list = ref([])
const page = ref(1)
const loadStatus = ref<'more'|'loading'|'noMore'>('more')

const loadData = async () => {
  if (loadStatus.value === 'noMore') return
  loadStatus.value = 'loading'
  const res = await getGoodsList({ page: page.value })
  list.value.push(...res.data.list)
  page.value++
  loadStatus.value = res.data.hasMore ? 'more' : 'noMore'
}

onMounted(loadData)
onReachBottom(loadData)
</script>

优势:逻辑聚合、类型推导友好、生命周期与 uniapp 钩子(onLoad, onShow, onReachBottom)天然融合。

3.2 Composables:业务逻辑的“积木”

将通用逻辑抽离为 composables,是 Vue3 工程化的核心。例如 useRequest.ts

// composables/useRequest.ts
import { ref } from 'vue'

export function useRequest<T>(api: (...args: any[]) => Promise<any>) {
  const data = ref<T | null>(null)
  const loading = ref(false)
  const error = ref<string | null>(null)

  const run = async (...args: any[]) => {
    loading.value = true
    error.value = null
    try {
      const res = await api(...args)
      data.value = res.data
      return res
    } catch (err: any) {
      error.value = err.message || '请求失败'
      throw err
    } finally {
      loading.value = false
    }
  }

  return { data, loading, error, run }
}

在页面中使用:

const { data: userInfo, run: fetchUser } = useRequest(getUserInfo)
fetchUser()

这种写法在多端(微信小程序 / H5 / App)中完全一致,极大降低了二开门槛。

3.3 Pinia 替代 Vuex

Uniapp Vue3 项目中,Pinia 已成为状态管理首选:
在这里插入图片描述

// store/user.ts
import { defineStore } from 'pinia'
import { ref } from 'vue'

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

  function setToken(val: string) {
    token.value = val
    uni.setStorageSync('token', val)
  }

  return { token, userInfo, setToken }
})

相比 Vuex,Pinia 去除了 mutations,更符合 Vue3 的响应式心智模型,且在 H5 和小程序中的表现一致。


四、微信小程序适配的关键点(Uniapp 特有)

虽然 Uniapp 抹平了大量差异,但在微信小程序中仍有一些必须处理的细节:

4.1 用户登录与 code2Session

微信小程序必须通过 wx.login 获取 code,再由后端换取 openid

// utils/auth.ts
export function wxLogin() {
  return new Promise((resolve, reject) => {
    uni.login({
      provider: 'weixin',
      success: (res) => {
        // 发送 res.code 到 PHP 后端
        resolve(res.code)
      },
      fail: reject
    })
  })
}

PHP 后端需要调用微信接口:

// 伪代码
$url = "https://api.weixin.qq.com/sns/jscode2session";
$params = [
  'appid' => env('WX_APPID'),
  'secret' => env('WX_SECRET'),
  'js_code' => $code,
  'grant_type' => 'authorization_code'
];
// 返回 openid / session_key

4.2 支付统一下单

微信小程序支付必须由后端发起:

// composables/usePayment.ts
export function usePayment() {
  const createOrder = async (orderId: string) => {
    const res = await uni.request({
      url: '/api/pay/create',
      method: 'POST',
      data: { order_id: orderId }
    })
    // 调起微信支付
    uni.requestPayment({
      ...res.data.payment_params,
      success: () => uni.showToast({ title: '支付成功' }),
      fail: () => uni.showToast({ title: '支付失败', icon: 'error' })
    })
  }
  return { createOrder }
}

PHP 端需生成 prepay_id,并按微信规则签名返回前端所需参数。

4.3 分包加载与体积控制

微信小程序主包限制 2MB(实际开发中建议控制在 1.5MB 内),Uniapp 通过 pages.json 配置分包:

{
  "subPackages": [
    {
      "root": "pages/sub/",
      "pages": [
        { "path": "detail", "style": { "navigationBarTitleText": "详情" } }
      ]
    }
  ]
}

同时,将大型第三方库(如 echarts)放入分包,或使用小程序专用版本(如 ec-canvas)。


五、PHP 后端:多端通用的接口设计

一套“多端通用”的 PHP 后端,核心在于接口与平台解耦

5.1 统一返回格式

// app/Controllers/BaseController.php
class BaseController
{
    protected function json($data = [], $code = 0, $msg = 'success')
    {
        return json_encode([
            'code' => $code,
            'msg'  => $msg,
            'data' => $data,
            'timestamp' => time()
        ], JSON_UNESCAPED_UNICODE);
    }
}

前端无论来自微信小程序、H5 还是 App,均按此格式解析。

5.2 平台识别与路由适配

通过请求头或参数区分平台:

$platform = $_SERVER['HTTP_PLATFORM'] ?? $_GET['platform'] ?? 'unknown';
switch ($platform) {
    case 'weixin':
        // 微信小程序逻辑(openid)
        break;
    case 'h5':
        // H5 逻辑(session/cookie)
        break;
    case 'app':
        // App 逻辑(device_id)
        break;
}

5.3 鉴权中间件

使用 JWT 或自定义 Token,在中间件中统一校验:

// app/Middleware/AuthMiddleware.php
public function handle($request, Closure $next)
{
    $token = $request->header('Authorization');
    if (!$this->verifyToken($token)) {
        return $this->json([], 401, '未授权');
    }
    return $next($request);
}

5.4 数据库设计与多端兼容

  • 用户表:users(id, openid, unionid, phone, platform)
  • 订单表:orders(id, user_id, amount, status, platform)
  • 日志表:logs(id, user_id, action, platform, created_at)

通过 platform 字段区分来源,方便后续统计与对账。


六、多端编译与条件编译实战

Uniapp 提供了强大的条件编译能力,解决各端差异:

<template>
  <!-- #ifdef MP-WEIXIN -->
  <button open-type="getPhoneNumber" @getphonenumber="onGetPhone">授权手机号</button>
  <!-- #endif -->

  <!-- #ifdef H5 -->
  <button @click="onInputPhone">输入手机号</button>
  <!-- #endif -->
</template>

<script setup>
// #ifdef MP-WEIXIN
const onGetPhone = (e) => { /* 微信逻辑 */ }
// #endif

// #ifdef H5
const onInputPhone = () => { /* H5 逻辑 */ }
// #endif
</script>

utils/env.ts 中封装平台判断:

export const isWeixin = process.env.VUE_APP_PLATFORM === 'mp-weixin'
export const isH5 = process.env.VUE_APP_PLATFORM === 'h5'

七、常见坑点与调试技巧

  1. 微信小程序不支持 DOM/BOM:不能使用 documentwindow,需改用 uni.createSelectorQuery
  2. 样式隔离问题:微信小程序默认样式隔离,Uniapp 中建议使用 scoped + deep 选择器。
  3. API 差异uni.navigateTo 在小程序中受页面栈限制(最多 10 层),H5 中无此限制。
  4. 真机调试:微信开发者工具无法完全模拟真机表现,务必使用 vConsole 或在 PHP 后端记录详细日志。
  5. HTTPS 强制:微信小程序要求所有接口必须为 HTTPS,PHP 后端需配置 SSL 证书。

在这里插入图片描述

八、源码交付与二开建议

一份合格的 Uniapp 小程序源码 交付物应包括:

  1. 前端源码:完整 src/ 目录,包含 composables/store/、条件编译示例。
  2. 后端源码:PHP 工程,含 .env.example、数据库 SQL、部署文档。
  3. 接口文档:Markdown 或 Swagger 格式的 API 说明。
  4. 环境配置manifest.jsonpages.json、微信小程序 appid 占位配置。
  5. 换肤指南:颜色变量位置、图标替换路径、广告位 ID 配置说明。

Uniapp 小程序源码 - Vue3+PHP多端通用 不仅仅是一个标题,它代表了一种工程化、标准化的交付形态:

  • 前端:以 Vue3 组合式 API 为核心,通过 composables 和 Pinia 实现逻辑复用与状态管理,利用条件编译适配多端。
  • 后端:PHP 采用分层架构,接口统一返回,通过平台标识实现多端兼容,保障数据安全与扩展性。
  • 交付:结构清晰、文档完备,既适合直接上线,也适合二次开发与源码交易。

对于开发者而言,掌握这套架构,意味着你不仅能快速交付一个微信小程序,更能以最小的成本覆盖 H5、App 等多个流量入口;对于购买源码的用户而言,这意味着更低的学习成本、更高的可维护性,以及真正的“一次开发,多端运行”。

Logo

一站式 AI 云服务平台

更多推荐