当前位置: 首页 > news >正文

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

文章目录

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


前言

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


🧩 总体设计哲学对比

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

🧱 布局方式详解对比

对比项FlutterVue 3React
布局核心机制使用 Widget 树,一切皆组件,比如 RowColumnExpandedHTML 标签 + CSS,如 div + flexJSX + 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-betweenJSX中用 div 加 class 控制 CSS Flex 或 styled-components
Grid布局GridView, SliverGrid 等自带 widgetCSS Grid同 Vue
Absolute 定位Stack + Positioned 实现层叠与绝对定位CSS 的 position: absolute同 Vue
条件渲染使用 if/? : 表达式嵌入 widgetv-if, v-show, 三元表达式if () return ...,或三元表达式

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

Flutter 示例

Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [Text("Left"),Text("Right"),],
)

Vue 3 示例(template)

<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)

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

class FadeInDemo extends StatefulWidget {_FadeInDemoState createState() => _FadeInDemoState();
}class _FadeInDemoState extends State<FadeInDemo> {double _opacity = 0.0;void initState() {super.initState();Future.delayed(Duration(milliseconds: 300), () {setState(() {_opacity = 1.0;});});}Widget build(BuildContext context) {return AnimatedOpacity(duration: Duration(milliseconds: 600),opacity: _opacity,child: Text("Hello World"),);}
}

Vue 3 示例(使用 <transition>

<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

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>;
}
.text {opacity: 0;transition: opacity 0.6s;
}
.fade-in {opacity: 1;
}

🧭 场景 2:Tab 切换布局

Flutter 示例(TabBar + TabBarView

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)

<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)

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

class SlideDemo extends StatefulWidget {_SlideDemoState createState() => _SlideDemoState();
}class _SlideDemoState extends State<SlideDemo> {bool moved = false;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)

<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)

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

📦 响应式/状态管理对比

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

🧠 总结对比学习建议

特性FlutterVue 3React
动画支持强大,组件级支持(如 Animated*原生 CSS 动画 + transition 插件原生 CSS 或动画库(framer-motion)
样式控制属性式控制,强结构性类 + CSS,配合 scoped 或 tailwindJSX 样式 + styled-components 等
状态响应setState / Riverpod / GetXref/reactive + watchuseState / useEffect
生命周期initState, build, disposeonMounted, onUnmounteduseEffect(() => {}, [])

http://www.dtcms.com/a/273568.html

相关文章:

  • 20.缓存问题与解决方案详解教程
  • 【Java】【力扣】102.二叉树层序遍历
  • 前端抓包(不启动前端项目就能进行后端调试)--whistle
  • 什么是DOM存储
  • 05 rk3568 debian11 root用户 声音服务PulseAudio不正常
  • Typecho架构深度剖析:轻量级博客系统的设计哲学与实现原理
  • 前端性能与可靠性工程:我们度量什么?核心 Web 指标与工具入门
  • 【氮化镓】不同偏压应力下电荷俘获效应导致的P-GaN HEMT阈值电压不稳定性
  • Chromium 136 编译指南 - Android 篇:从Linux版切换到Android版(六)
  • 电子基石:硬件工程师的器件手册 (四) - 二极管:电流的单向阀与电路的守护神
  • SSL与HTTP概述
  • 神经网络的参数初始化
  • 【数据结构与算法】203.移除链表元素(LeetCode)图文详解
  • Pandas:数据分箱
  • 使用Python和AkShare轻松获取新闻联播文字稿:从数据获取到文本挖掘
  • 剑指offer——链表:从尾到头打印链表
  • 自用docker记录
  • 学习C++、QT---21(QT中QFile库的QFile读取文件、写入文件的讲解)
  • 部署 React + Vite + TypeScript 项目到阿里云 ECS
  • ARMv9架构
  • tcp/quic 的滑动窗口
  • 飞算 JavaAI 体验:重塑 Java 开发的智能新范式
  • Element Plus和Ant Design Vue深度对比分析与选型指南
  • WD0407 40V 7A 超级肖特基二极管,应用于开关汽车工业控制
  • 【字节跳动】数据挖掘面试题0015:100 亿个单词,找出出现频率最高的单词。要求几种方案
  • 20250711荣品RD-RK3588开发板在Android13下的开机自启动的配置步骤
  • React之旅-05 List Key
  • 进制转换原理与实现详解
  • cyvcf2 知识点详解
  • MYSQL C_API使用全解