浅谈 Vue & React & Flutter 框架

文章目录

    • 前言
    • 框架概述对比
    • 创建项目
      • [Vite + Vue,React 项目创建](#Vite + Vue,React 项目创建)
      • [Flutter 项目创建](#Flutter 项目创建)
    • [1. 计数器应用示例](#1. 计数器应用示例)
    • [2. 列表数据展示示例](#2. 列表数据展示示例)
      • [Vue 列表渲染](#Vue 列表渲染)
      • [React 列表渲染](#React 列表渲染)
      • [Flutter 列表渲染](#Flutter 列表渲染)
    • 核心差异分析
      • [1. 语法差异](#1. 语法差异)
      • [2. 数据绑定](#2. 数据绑定)
      • [3. 样式处理](#3. 样式处理)
    • 对比总结

前言

最近学习了 Vue.js、React、Flutter 这三个框架,如果用一句话来总结,那么:

bash 复制代码
# Web 端
Vue: 一切皆模板
React: 一切皆方法

# 移动端
Flutter: 一切皆对象

如果让我这个后端开发出身的人来选,Web 端我会选 React,移动端我会选 Flutter,我比较偏爱对象,方法,看到它们会感到很亲切。

框架概述对比

特性 Vue.js React Flutter
类型 JavaScript框架 JavaScript库 UI SDK(跨平台)
语言 JavaScript/TypeScript JavaScript/TSX Dart
架构模式 MVVM 组件化(虚拟DOM) 响应式(Widget树)
学习曲线 平缓 中等 较陡(需学Dart)
渲染方式 虚拟DOM 虚拟DOM Canvas/Skia直接渲染
跨平台 通过工具链 通过React Native 原生支持
性能 优秀 优秀 接近原生
状态管理 Vuex/Pinia Redux/MobX/Context Provider/Bloc/Riverpod

创建项目

Vite + Vue,React 项目创建

创建一个 vite 项目,可以选择 React,Vue 框架,这样我们就能得到一个基础的项目结构来运行对比,例如 Vue 项目创建:

bash 复制代码
$ pnpm create vite@latest
│
◇  Project name:
│  vite-project
│
◆  Select a framework:
│  ○ Vanilla
│  ● Vue
│  ○ React
│  ○ Preact
│  ○ Lit
│  ○ Svelte
│  ○ Solid
│  ○ Qwik
│  ○ Angular
│  ○ Marko
│  ○ Others
◆  Select a variant:
│  ● TypeScript
│  ○ JavaScript
│  ○ Official Vue Starter ↗
│  ○ Nuxt ↗
│  ○ Vike ↗
◆  Use rolldown-vite (Experimental)?:
│  ○ Yes
│  ● No
◆  Install with pnpm and start now?
│  ○ Yes / ● No
│
└  Done. Now run:

  cd vite-project
  pnpm install
  pnpm dev

Flutter 项目创建

创建一个 Flutter 项目,例如 counter_app:

bash 复制代码
flutter create counter_app

1. 计数器应用示例

Vue 3 (Composition API)

src/components/HelloWorld.vue

html 复制代码
<!-- src/components/HelloWorld.vue -->
<script setup lang="ts">
import { ref } from "vue";

defineProps<{ msg: string }>();

const count = ref(0);
</script>

<template>
  <h1>{{ msg }}</h1>

  <div class="card">
    <button type="button" @click="count++">count is {{ count }}</button>
  </div>
</template>

src/components/index.ts

ts 复制代码
import HelloWorld from "./HelloWorld.vue";

export { HelloWorld };

src/App.vue

html 复制代码
<!-- src/App.vue -->
<script setup lang="ts">
import { HelloWorld } from "./components";
</script>

<template>
  <HelloWorld msg="Vite + Vue" />
</template>

React (函数组件 + Hooks)

src/App.tsx

ts 复制代码
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";

function App(props: { name: string }) {
  const [count, setCount] = useState(0);

  return (
    <>
      <h1>{props.name}</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
      </div>
    </>
  );
}

export default App;

src/main.tsx,调用 App 组件 <App name="Vite + React" />,其实,可以这样看待 App(xxx),就像调用函数一样

ts 复制代码
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.tsx";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <App name="Vite + React" />
  </StrictMode>,
);

运行对比:

Flutter (Dart)

lib/main.dart

dart 复制代码
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(colorScheme: .fromSeed(seedColor: Colors.deepPurple)),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,

        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: .center,
          children: [
            const Text('You have pushed the button this many times:'),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

Flutter 就像是在做 java 开发,全是对象,通过对象的组合来构建 UI,我想后端应该可以无缝切换到 Flutter 开发吧。

运行效果:

2. 列表数据展示示例

Vue 列表渲染

html 复制代码
<template>
  <div>
    <ul>
      <li v-for="item in items" :key="item.id">
        {{ item.name }} - {{ item.price }}元
      </li>
    </ul>
  </div>
</template>

<script setup lang="ts">
const items = [
  { id: 1, name: "苹果", price: 5 },
  { id: 2, name: "香蕉", price: 3 },
  { id: 3, name: "橙子", price: 4 },
];
</script>

React 列表渲染

js 复制代码
function ItemList() {
  const items = [
    { id: 1, name: "苹果", price: 5 },
    { id: 2, name: "香蕉", price: 3 },
    { id: 3, name: "橙子", price: 4 },
  ];

  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>
          {item.name} - {item.price}元
        </li>
      ))}
    </ul>
  );
}

Flutter 列表渲染

dart 复制代码
ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    final item = items[index];
    return ListTile(
      title: Text(item.name),
      subtitle: Text('${item.price}元'),
    );
  },
);

核心差异分析

1. 语法差异

  • Vue: 模板语法,分离的HTML/CSS/JS
  • React: JSX,JavaScript中写HTML
  • Flutter: Widget树,完全用代码构建UI

2. 数据绑定

  • Vue: 双向绑定(v-model)
html 复制代码
<input v-model="message" />
  • React: 单向数据流
js 复制代码
<input value={message} onChange={(e) => setMessage(e.target.value)} />
  • Flutter: 通过Controller
dart 复制代码
TextEditingController _controller = TextEditingController();
TextField(controller: _controller);

3. 样式处理

html 复制代码
<!-- Vue:Scoped CSS -->
<style scoped>
.button {
  background: blue;
}
</style>
js 复制代码
// React:CSS-in-JS
const styles = {
  button: {
    background: "blue",
  },
};
<button style={styles.button}>Click</button>;
dart 复制代码
// Flutter:完全代码化
ElevatedButton(
  style: ElevatedButton.styleFrom(
    backgroundColor: Colors.blue,
  ),
  child: Text('Click'),
)

对比总结

用 Vue 或 React 开发 Web 端应用,用浏览器访问,用 Flutter 开发移动端应用,可以在不同系统手机上运行。

  1. Vue 就像是模板中填充数据,React 就像是在 JS 中拼装 HTML,它们本质上还是 html,通过浏览器渲染出来
  2. Flutter 或原生(Android, iOS)开发就像是以前用 VB 开发应用一样,控件 要用它们自己的,而不是用 html 来写
相关推荐
恋猫de小郭5 分钟前
Kotlin Toolchain 0.13,JetBrains 推荐 KMP 都切换到到全新工具链
android·前端·flutter
高级程序源6 分钟前
hive电商平台商品销售数据分析与趋势预测45659-计算机课程设计、毕业设计
vue.js·hive·spring boot·mysql·数据分析·django·课程设计
m0_7381858211 分钟前
Flutter 鸿蒙化实战:rive 适配 OpenHarmony,Rive 动画
flutter·华为·harmonyos·鸿蒙
晓得迷路了23 分钟前
栗子前端技术周刊第 149 期 - Vite+ 1.0、Preact 11、Next.js 16.4...
前端·javascript·react.js
song50135 分钟前
React Native for OpenHarmony 实战:三方库 react-native-popup-menu 的鸿蒙化适配指南
css·深度学习·react native·react.js·transformer·harmonyos
ljt272496066138 分钟前
Vue笔记(十三)--mixin
vue.js·笔记
haluhalu.1 小时前
Agent = LLM + 上下文 + 工具(含观察 / 动作空间、ReAct 循环)
前端·javascript·人工智能·python·react.js·机器学习·个人开发
weixin_4481199410 小时前
Datawhale Easy Data × AI:构建知识与记忆驱动的 Agent笔记8
人工智能·笔记·react.js
Geek_Vison12 小时前
保险APP已经用了Flutter,还能接入小程序吗?
flutter·小程序·uni-app·mpaas·小程序容器
FungLeo12 小时前
成为全栈·Flutter App 篇·go_router 与四 Tab App Shell:保留导航状态、深链和登录回跳
flutter·移动开发·成为全栈·go_router·路由设计·深链接