Flutter、Vue 3 和 React 在 UI 布局比较

文章目录

  • 前言
    • [🧩 总体设计哲学对比](#🧩 总体设计哲学对比)
    • [🧱 布局方式详解对比](#🧱 布局方式详解对比)
    • [🧭 示例对比:Flex 布局(横向排列)](#🧭 示例对比:Flex 布局(横向排列))
      • [Flutter 示例](#Flutter 示例)
      • [Vue 3 示例(template)](#Vue 3 示例(template))
      • [React 示例(JSX)](#React 示例(JSX))
    • [🧩 场景 1:页面加载时淡入(入场动画)](#🧩 场景 1:页面加载时淡入(入场动画))
      • [Flutter 示例(使用 `AnimatedOpacity`)](#Flutter 示例(使用 AnimatedOpacity))
      • [Vue 3 示例(使用 `<transition>`)](#Vue 3 示例(使用 <transition>))
      • [React 示例(使用 CSS Transition + `useEffect`)](#React 示例(使用 CSS Transition + useEffect))
    • [🧭 场景 2:Tab 切换布局](#🧭 场景 2:Tab 切换布局)
      • [Flutter 示例(`TabBar` + `TabBarView`)](#Flutter 示例(TabBar + TabBarView))
      • [Vue 3 示例(配合 Element Plus 或自定义 Tab)](#Vue 3 示例(配合 Element Plus 或自定义 Tab))
      • [React 示例(配合 Ant Design 或自定义 Tab)](#React 示例(配合 Ant Design 或自定义 Tab))
    • [🎮 场景 3:点击按钮后元素平移动画(Translate 动画)](#🎮 场景 3:点击按钮后元素平移动画(Translate 动画))
      • [Flutter 示例(`AnimatedPositioned` + `Stack`)](#Flutter 示例(AnimatedPositioned + Stack))
      • [Vue 3 示例(CSS 动画 + 绑定 style)](#Vue 3 示例(CSS 动画 + 绑定 style))
      • [React 示例(CSS 绑定 style)](#React 示例(CSS 绑定 style))
    • [📦 响应式/状态管理对比](#📦 响应式/状态管理对比)
    • [🧠 总结对比学习建议](#🧠 总结对比学习建议)

前言

Flutter、Vue 3 和 React 在 UI 布局方式上的设计哲学和实现方式比较


🧩 总体设计哲学对比

项目 Flutter Vue 3 React
编程语言 Dart JavaScript / TypeScript JavaScript / TypeScript
渲染方式 自绘 UI(Skia 引擎) HTML + CSS(DOM) HTML + CSS(DOM)
样式机制 通过 Widget 实现 单文件组件 + CSS(或 scoped CSS) JSX + CSS-in-JS / CSS Modules 等
布局方式 Widget 嵌套布局 基于 HTML 结构和 CSS 布局模型 同 Vue,靠 CSS 控制布局

🧱 布局方式详解对比

对比项 Flutter Vue 3 React
布局核心机制 使用 Widget 树 ,一切皆组件,比如 RowColumnExpanded HTML 标签 + CSS,如 div + flex JSX + CSS(或 styled-components)
样式设置方式 通过属性传递(如 padding: EdgeInsets.all(10) CSS 样式或 scoped 样式 CSS、styled-components、emotion、Tailwind 等
响应式布局 使用 LayoutBuilderMediaQueryFlexible 控制自适应 使用媒体查询 + CSS Flex/Grid 等 同 Vue,依赖 CSS 的能力
Flex布局 Row/Column + Expanded/Flexible 控制主轴和交叉轴方向 CSS Flex,例如 display: flex; justify-content: space-between JSX中用 div 加 class 控制 CSS Flex 或 styled-components
Grid布局 GridView, SliverGrid 等自带 widget CSS Grid 同 Vue
Absolute 定位 Stack + Positioned 实现层叠与绝对定位 CSS 的 position: absolute 同 Vue
条件渲染 使用 if/? : 表达式嵌入 widget v-if, v-show, 三元表达式 if () return ...,或三元表达式

🧭 示例对比:Flex 布局(横向排列)

Flutter 示例

dart 复制代码
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    Text("Left"),
    Text("Right"),
  ],
)

Vue 3 示例(template)

html 复制代码
<template>
  <div class="flex-container">
    <span>Left</span>
    <span>Right</span>
  </div>
</template>

<style scoped>
.flex-container {
  display: flex;
  justify-content: space-between;
}
</style>

React 示例(JSX)

js 复制代码
function App() {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between' }}>
      <span>Left</span>
      <span>Right</span>
    </div>
  );
}

好的,我们来通过 实际开发中常见的 UI 场景 ,对比 Flutter、Vue 3 和 React 的实现方式,重点包括 布局、动画、交互、状态管理等方面。每个场景都提供三者的代码示例,以便你直观对比和学习。


🧩 场景 1:页面加载时淡入(入场动画)

Flutter 示例(使用 AnimatedOpacity

dart 复制代码
class FadeInDemo extends StatefulWidget {
  @override
  _FadeInDemoState createState() => _FadeInDemoState();
}

class _FadeInDemoState extends State<FadeInDemo> {
  double _opacity = 0.0;

  @override
  void initState() {
    super.initState();
    Future.delayed(Duration(milliseconds: 300), () {
      setState(() {
        _opacity = 1.0;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedOpacity(
      duration: Duration(milliseconds: 600),
      opacity: _opacity,
      child: Text("Hello World"),
    );
  }
}

Vue 3 示例(使用 <transition>

js 复制代码
<template>
  <transition name="fade">
    <div v-if="show" class="text">Hello World</div>
  </transition>
</template>

<script setup>
import { ref, onMounted } from 'vue'
const show = ref(false)

onMounted(() => {
  setTimeout(() => show.value = true, 300)
})
</script>

<style scoped>
.fade-enter-active {
  transition: opacity 0.6s;
}
.fade-enter-from {
  opacity: 0;
}
.fade-enter-to {
  opacity: 1;
}
</style>

React 示例(使用 CSS Transition + useEffect

js 复制代码
import { useState, useEffect } from "react";
import "./App.css";

export default function App() {
  const [show, setShow] = useState(false);
  useEffect(() => {
    setTimeout(() => setShow(true), 300);
  }, []);
  
  return <div className={`text ${show ? "fade-in" : ""}`}>Hello World</div>;
}
css 复制代码
.text {
  opacity: 0;
  transition: opacity 0.6s;
}
.fade-in {
  opacity: 1;
}

🧭 场景 2:Tab 切换布局

Flutter 示例(TabBar + TabBarView

dart 复制代码
DefaultTabController(
  length: 2,
  child: Scaffold(
    appBar: AppBar(
      bottom: TabBar(
        tabs: [
          Tab(text: "Home"),
          Tab(text: "Profile"),
        ],
      ),
    ),
    body: TabBarView(
      children: [
        Center(child: Text("Home Page")),
        Center(child: Text("Profile Page")),
      ],
    ),
  ),
)

Vue 3 示例(配合 Element Plus 或自定义 Tab)

js 复制代码
<template>
  <el-tabs v-model="activeTab">
    <el-tab-pane label="Home" name="home">Home Page</el-tab-pane>
    <el-tab-pane label="Profile" name="profile">Profile Page</el-tab-pane>
  </el-tabs>
</template>

<script setup>
import { ref } from 'vue'
const activeTab = ref('home')
</script>

React 示例(配合 Ant Design 或自定义 Tab)

js 复制代码
import { Tabs } from "antd";
const { TabPane } = Tabs;

export default function App() {
  return (
    <Tabs defaultActiveKey="1">
      <TabPane tab="Home" key="1">Home Page</TabPane>
      <TabPane tab="Profile" key="2">Profile Page</TabPane>
    </Tabs>
  );
}

🎮 场景 3:点击按钮后元素平移动画(Translate 动画)

Flutter 示例(AnimatedPositioned + Stack

dart 复制代码
class SlideDemo extends StatefulWidget {
  @override
  _SlideDemoState createState() => _SlideDemoState();
}

class _SlideDemoState extends State<SlideDemo> {
  bool moved = false;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        AnimatedPositioned(
          left: moved ? 200 : 0,
          duration: Duration(milliseconds: 500),
          child: ElevatedButton(
            onPressed: () => setState(() => moved = !moved),
            child: Text("Move Me"),
          ),
        ),
      ],
    );
  }
}

Vue 3 示例(CSS 动画 + 绑定 style)

js 复制代码
<template>
  <button :style="style" @click="toggle">Move Me</button>
</template>

<script setup>
import { ref, computed } from 'vue'
const moved = ref(false)
const toggle = () => moved.value = !moved.value
const style = computed(() => ({
  transform: `translateX(${moved.value ? '200px' : '0px'})`,
  transition: 'transform 0.5s'
}))
</script>

React 示例(CSS 绑定 style)

js 复制代码
import { useState } from "react";

export default function App() {
  const [moved, setMoved] = useState(false);
  return (
    <button
      onClick={() => setMoved(!moved)}
      style={{
        transform: `translateX(${moved ? "200px" : "0px"})`,
        transition: "transform 0.5s"
      }}
    >
      Move Me
    </button>
  );
}

📦 响应式/状态管理对比

功能 Flutter Vue 3 React
响应式机制 setState / Provider / Riverpod 等 ref, reactive useState, useEffect
组件更新机制 自动刷新使用该状态的 widget 响应式引用追踪 函数组件执行时重新渲染

🧠 总结对比学习建议

特性 Flutter Vue 3 React
动画支持 强大,组件级支持(如 Animated* 原生 CSS 动画 + transition 插件 原生 CSS 或动画库(framer-motion)
样式控制 属性式控制,强结构性 类 + CSS,配合 scoped 或 tailwind JSX 样式 + styled-components 等
状态响应 setState / Riverpod / GetX ref/reactive + watch useState / useEffect
生命周期 initState, build, dispose onMounted, onUnmounted useEffect(() => {}, [])

相关推荐
伍哥的传说31 分钟前
React 自定义Hook——页面或元素滚动到底部监听 Hook
前端·react.js·前端框架
小彭努力中4 小时前
147.在 Vue3 中使用 OpenLayers 地图上 ECharts 模拟飞机循环飞行
前端·javascript·vue.js·ecmascript·echarts
怀君6 小时前
Flutter——数据库Drift开发详细教程之迁移(九)
数据库·flutter
人生游戏牛马NPC1号6 小时前
学习 Flutter (一)
android·学习·flutter
GeniuswongAir6 小时前
如何在Flutter开发中系统性减少知识盲区
flutter
冰天糖葫芦6 小时前
VUE实现数字翻牌效果
前端·javascript·vue.js
西瓜_号码7 小时前
React中Redux基础和路由介绍
javascript·react.js·ecmascript
伟笑8 小时前
React 的常用钩子函数在Vue中是如何设计体现出来的。
前端·react.js
0wioiw09 小时前
Flutter基础(前端教程②-卡片列表)
flutter