浅谈 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 来写
相关推荐
maaath20 小时前
【maaath】 OpenHarmony 设备信息获取能力集成指南
flutter·华为·harmonyos
朝阳3921 小时前
react【实战】搜索框(含联动动画,清空按钮)
前端·javascript·react.js
Hello__777721 小时前
开源鸿蒙 Flutter 实战|帮助中心功能全流程实现
flutter·开源·harmonyos
Hello__777721 小时前
开源鸿蒙 Flutter 实战|用户认证标识功能全流程实现
flutter·开源·harmonyos
吃西瓜的年年21 小时前
react(五)路由
前端·react.js·前端框架
Hello__777721 小时前
开源鸿蒙 Flutter 实战|用户详情页按钮布局溢出全流程修复与最佳实践
flutter·开源·harmonyos
涵涵(互关)21 小时前
语法大全-only-writer
开发语言·前端·vue.js·typescript
恋猫de小郭1 天前
Flutter 3.41.8 又双叒修复调试问题,草台班子日常 hotfix
android·前端·flutter
liulian09161 天前
【Flutter for OpenHarmony第三方库】Flutter for OpenHarmony 离线模式实现:让你的应用无网也能萌萌哒~
开发语言·flutter·华为·php·学习方法·harmonyos
Lanren的编程日记1 天前
Flutter 鸿蒙应用手势导航系统实战:自定义手势识别+手势导航+冲突处理,打造流畅交互体验
flutter·交互·harmonyos