浅谈 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 来写
相关推荐
kuntli6 小时前
Vue生命周期全解析
vue.js
小一梦7 小时前
宝塔面板单域名部署多个 Vue 项目:从路径冲突到完美共存
服务器·javascript·vue.js
牛马1117 小时前
Flutter CustomPainter
flutter
只能是遇见7 小时前
SpringBoot + vue 管理系统
vue.js·spring boot·后端
蜡台7 小时前
Flutter 安装配置
android·java·flutter·环境变量
加农炮手Jinx7 小时前
Flutter 组件 ubuntu_service 适配鸿蒙 HarmonyOS 实战:底层系统服务治理,构建鸿蒙 Linux 子系统与守护进程交互架构
flutter·harmonyos·鸿蒙·openharmony·ubuntu_service
里欧跑得慢7 小时前
Flutter 三方库 mobx_codegen — 自动化驱动的高性能响应式状态管理(适配鸿蒙 HarmonyOS Next ohos)
flutter·自动化·harmonyos
王码码20357 小时前
Flutter 三方库 login_client 的鸿蒙化适配指南 - 打造工业级安全登录、OAuth2 自动化鉴权、鸿蒙级身份守门员
flutter·harmonyos·鸿蒙·openharmony·login_client
加农炮手Jinx7 小时前
Flutter 三方库 cloudflare 鸿蒙云边协同分发流适配精讲:直连全球高速存储网关阵列无缝吞吐海量动静态画像资源,构筑大吞吐业务级网络负载安全分流-适配鸿蒙 HarmonyOS ohos
网络·flutter·harmonyos