Skip to content

跨端开发方案对比

跨端开发是指使用一套代码构建多个平台的应用,包括小程序、H5、App 等。

主流方案概览

框架技术栈支持平台出品方特点
uni-appVue小程序/H5/AppDCloud生态丰富,上手简单
TaroReact/Vue小程序/H5/RN京东语法现代,插件系统强大
React NativeReactiOS/AndroidMeta原生体验,成熟稳定
FlutterDartiOS/Android/WebGoogle高性能,自绘引擎
WeexVueiOS/Android阿里接近原生,维护减少

uni-app

简介

uni-app 是 DCloud 推出的跨端框架,基于 Vue.js,支持编译到多个平台。

支持平台

  • 微信/支付宝/百度/字节/QQ/快手/京东小程序
  • H5
  • App(iOS/Android)
  • 快应用

项目结构

├── pages/                # 页面
│   ├── index/
│   │   └── index.vue
│   └── user/
│       └── user.vue
├── components/           # 组件
├── static/               # 静态资源
├── store/                # Vuex
├── App.vue               # 应用入口
├── main.js               # 入口文件
├── manifest.json         # 应用配置
├── pages.json            # 页面配置
└── uni.scss              # 全局样式变量

基本示例

vue
<template>
  <view class="container">
    <text class="title">{{ message }}</text>
    <button @click="handleClick">点击</button>
    <view v-for="item in list" :key="item.id">
      {{ item.name }}
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello uni-app',
      list: []
    }
  },
  onLoad(options) {
    // 页面加载
    console.log('页面参数:', options)
  },
  onShow() {
    // 页面显示
  },
  methods: {
    handleClick() {
      uni.showToast({
        title: '点击了',
        icon: 'success'
      })
    }
  }
}
</script>

<style>
.container {
  padding: 20rpx;
}
.title {
  font-size: 32rpx;
}
</style>

条件编译

vue
<template>
  <!-- #ifdef MP-WEIXIN -->
  <text>微信小程序专属</text>
  <!-- #endif -->

  <!-- #ifdef H5 -->
  <text>H5 专属</text>
  <!-- #endif -->

  <!-- #ifndef APP-PLUS -->
  <text>非 App 平台</text>
  <!-- #endif -->
</template>

<script>
export default {
  onLoad() {
    // #ifdef MP-WEIXIN
    console.log('微信小程序')
    // #endif

    // #ifdef H5
    console.log('H5')
    // #endif
  }
}
</script>

<style>
/* #ifdef MP-WEIXIN */
.special {
  color: green;
}
/* #endif */
</style>

API 调用

javascript
// 路由
uni.navigateTo({ url: '/pages/detail/detail?id=1' })
uni.redirectTo({ url: '/pages/login/login' })
uni.switchTab({ url: '/pages/home/home' })
uni.navigateBack({ delta: 1 })

// 网络请求
uni.request({
  url: 'https://api.example.com/data',
  method: 'GET',
  data: { page: 1 },
  success: (res) => {
    console.log(res.data)
  }
})

// 存储
uni.setStorageSync('token', 'xxx')
const token = uni.getStorageSync('token')

// 获取系统信息
const systemInfo = uni.getSystemInfoSync()
console.log(systemInfo.platform)

Taro

简介

Taro 是京东推出的多端统一开发框架,支持 React、Vue 等主流框架。

支持平台

  • 微信/支付宝/百度/字节/QQ/京东小程序
  • H5
  • React Native
  • 快应用

项目结构

├── config/               # 配置
│   ├── index.js
│   ├── dev.js
│   └── prod.js
├── src/
│   ├── pages/            # 页面
│   ├── components/       # 组件
│   ├── services/         # API 服务
│   ├── store/            # 状态管理
│   ├── app.config.ts     # 应用配置
│   ├── app.tsx           # 应用入口
│   └── app.scss          # 全局样式
├── project.config.json   # 小程序配置
└── package.json

基本示例(React)

tsx
import { View, Text, Button } from '@tarojs/components'
import { useState } from 'react'
import Taro, { useLoad, useReady } from '@tarojs/taro'
import './index.scss'

export default function Index() {
  const [count, setCount] = useState(0)

  useLoad((options) => {
    console.log('页面加载', options)
  })

  useReady(() => {
    console.log('页面初次渲染完成')
  })

  const handleClick = () => {
    setCount(c => c + 1)
    Taro.showToast({
      title: '点击了',
      icon: 'success'
    })
  }

  return (
    <View className="container">
      <Text className="title">Count: {count}</Text>
      <Button onClick={handleClick}>增加</Button>
    </View>
  )
}

基本示例(Vue 3)

vue
<template>
  <view class="container">
    <text class="title">Count: {{ count }}</text>
    <button @tap="handleClick">增加</button>
  </view>
</template>

<script setup>
import { ref } from 'vue'
import Taro, { useLoad, useReady } from '@tarojs/taro'

const count = ref(0)

useLoad((options) => {
  console.log('页面加载', options)
})

useReady(() => {
  console.log('页面初次渲染完成')
})

const handleClick = () => {
  count.value++
  Taro.showToast({
    title: '点击了',
    icon: 'success'
  })
}
</script>

多端适配

tsx
import { View } from '@tarojs/components'
import Taro from '@tarojs/taro'

function Component() {
  // 获取当前环境
  const env = Taro.getEnv()

  // 环境判断
  if (process.env.TARO_ENV === 'weapp') {
    // 微信小程序
  }

  if (process.env.TARO_ENV === 'h5') {
    // H5
  }

  return (
    <View>
      {process.env.TARO_ENV === 'weapp' && <View>微信专属</View>}
      {process.env.TARO_ENV === 'h5' && <View>H5 专属</View>}
    </View>
  )
}

React Native

简介

React Native 是 Meta(原 Facebook)推出的移动端跨平台框架,使用 JavaScript 和 React 构建原生应用。

架构

JavaScript 代码

  JavaScript 引擎 (Hermes/JSC)

  Bridge / JSI (新架构)

  Native Modules

  iOS / Android 原生组件

新架构(Fabric + TurboModules)

  • Fabric:新的渲染系统,支持同步渲染
  • TurboModules:新的原生模块系统,按需加载
  • JSI:JavaScript Interface,替代 Bridge

基本示例

tsx
import React, { useState } from 'react'
import {
  View,
  Text,
  StyleSheet,
  TouchableOpacity,
  FlatList
} from 'react-native'

export default function App() {
  const [count, setCount] = useState(0)
  const [items, setItems] = useState([
    { id: '1', title: 'Item 1' },
    { id: '2', title: 'Item 2' }
  ])

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Count: {count}</Text>

      <TouchableOpacity
        style={styles.button}
        onPress={() => setCount(c => c + 1)}
      >
        <Text style={styles.buttonText}>增加</Text>
      </TouchableOpacity>

      <FlatList
        data={items}
        keyExtractor={(item) => item.id}
        renderItem={({ item }) => (
          <View style={styles.item}>
            <Text>{item.title}</Text>
          </View>
        )}
      />
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff'
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold'
  },
  button: {
    backgroundColor: '#007AFF',
    padding: 12,
    borderRadius: 8,
    marginTop: 20
  },
  buttonText: {
    color: '#fff',
    textAlign: 'center'
  },
  item: {
    padding: 16,
    borderBottomWidth: 1,
    borderBottomColor: '#eee'
  }
})

平台特定代码

tsx
// Button.ios.tsx
export default function Button() {
  return <IOSButton />
}

// Button.android.tsx
export default function Button() {
  return <AndroidButton />
}

// 使用
import Button from './Button'  // 自动选择正确的文件

// Platform API
import { Platform } from 'react-native'

const styles = StyleSheet.create({
  container: {
    paddingTop: Platform.OS === 'ios' ? 20 : 0,
    ...Platform.select({
      ios: { shadowColor: 'black' },
      android: { elevation: 4 }
    })
  }
})

Flutter

简介

Flutter 是 Google 推出的跨平台 UI 框架,使用 Dart 语言,采用自绘引擎 Skia。

架构

Dart 代码 (Widget)

  Flutter Framework

  Skia 渲染引擎

  平台 Canvas

基本示例

dart
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _count = 0;

  void _increment() {
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Count: $_count', style: TextStyle(fontSize: 24)),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _increment,
              child: Text('增加'),
            ),
          ],
        ),
      ),
    );
  }
}

方案对比

性能对比

框架渲染方式性能包体积
uni-appWebView/原生中等
TaroWebView/原生中等
React Native原生组件较好中等
Flutter自绘引擎最好较大

开发体验

框架热重载调试工具生态
uni-app支持HBuilder丰富
Taro支持各平台工具丰富
React Native支持Flipper丰富
Flutter支持DevTools增长中

适用场景

场景推荐方案
小程序为主uni-app / Taro
React 技术栈Taro / React Native
Vue 技术栈uni-app / Taro
高性能要求Flutter / React Native
快速迭代uni-app
原生体验React Native / Flutter

选型建议

选择 uni-app

  • 团队熟悉 Vue
  • 需要快速上线
  • 以小程序为主要平台
  • 需要丰富的插件市场

选择 Taro

  • 团队熟悉 React
  • 需要灵活的架构
  • 需要强大的插件系统
  • 希望代码更现代化

选择 React Native

  • 团队熟悉 React
  • 主要做 App
  • 需要接近原生的体验
  • 需要成熟的社区支持

选择 Flutter

  • 追求最佳性能
  • UI 一致性要求高
  • 愿意学习 Dart
  • 需要自定义 UI

常见面试题

1. 跨端开发的原理是什么?

不同框架有不同实现:

  • 编译时转换:uni-app/Taro 将代码编译为各平台代码
  • 运行时桥接:React Native 通过 Bridge 调用原生组件
  • 自绘引擎:Flutter 使用 Skia 自己绘制 UI

2. uni-app 和 Taro 如何实现多端?

通过编译时转换:

  • 将框架代码转换为目标平台代码
  • 使用条件编译处理平台差异
  • 封装统一 API 适配各平台

3. React Native 新架构有什么改进?

  • JSI:替代 Bridge,支持同步调用
  • Fabric:新渲染系统,性能更好
  • TurboModules:按需加载原生模块
  • Codegen:类型安全的原生接口

4. 如何选择跨端方案?

考虑因素:

  • 目标平台:小程序为主还是 App 为主
  • 团队技术栈:Vue 还是 React
  • 性能要求:普通应用还是高性能应用
  • 开发效率:快速迭代还是长期维护