Flutter Web:混合开发的最佳实践

Flutter Web:混合开发的最佳实践

一次编写,多端运行。Flutter Web 让前端开发更加高效。

一、Flutter Web 的优势

作为一名追求像素级还原的 UI 匠人,我对跨平台解决方案有着严格的要求。Flutter Web 不仅让我们能够使用相同的代码库构建 Android、iOS 和 Web 应用,还提供了出色的性能和一致的用户体验。它就像是一把瑞士军刀,为前端开发带来了前所未有的便利。

二、环境搭建

1. 启用 Web 支持

# 启用 Web 支持 flutter config --enable-web # 检查可用设备 flutter devices # 创建项目 flutter create my_web_app cd my_web_app # 运行 Web 应用 flutter run -d chrome 

2. 项目结构

my_web_app/ lib/ main.dart # 主入口 home_screen.dart # 主屏幕 components/ # 组件 services/ # 服务 web/ # Web 特定文件 index.html # HTML 入口 manifest.json # PWA 配置 icons/ # 图标 pubspec.yaml # 依赖配置 

三、基础实现

1. 简单的 Web 应用

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 Web Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: const HomeScreen(), ); } } class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override _HomeScreenState createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Flutter Web Demo'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ const Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.headline4, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), ); } } 

四、Web 特定功能

1. 响应式布局

class ResponsiveLayout extends StatelessWidget { final Widget mobileLayout; final Widget tabletLayout; final Widget desktopLayout; const ResponsiveLayout({ Key? key, required this.mobileLayout, required this.tabletLayout, required this.desktopLayout, }) : super(key: key); @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { if (constraints.maxWidth < 600) { return mobileLayout; } else if (constraints.maxWidth < 1024) { return tabletLayout; } else { return desktopLayout; } }, ); } } // 使用 class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return ResponsiveLayout( mobileLayout: MobileHome(), tabletLayout: TabletHome(), desktopLayout: DesktopHome(), ); } } 

2. 平台检测

import 'package:flutter/foundation.dart'; class PlatformAwareWidget extends StatelessWidget { @override Widget build(BuildContext context) { if (kIsWeb) { // Web 特定实现 return WebSpecificWidget(); } else if (Platform.isAndroid) { // Android 特定实现 return AndroidSpecificWidget(); } else if (Platform.isIOS) { // iOS 特定实现 return IOSSpecificWidget(); } else { // 通用实现 return CommonWidget(); } } } 

3. 与 Web API 交互

import 'dart:js' as js; class WebInteropWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Column( children: [ ElevatedButton( onPressed: () { // 调用 JavaScript 函数 js.context.callMethod('alert', ['Hello from Flutter!']); }, child: Text('Show Alert'), ), ElevatedButton( onPressed: () { // 访问 DOM js.context['document'].callMethod('title', ['Flutter Web App']); }, child: Text('Change Title'), ), ], ); } } 

五、性能优化

1. 代码分割

// main.dart void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( routes: { '/': (context) => HomePage(), '/details': (context) => DetailsPage(), }, ); } } // details_page.dart class DetailsPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Details')), body: Center(child: Text('Details Page')), ); } } 

2. 图片优化

class OptimizedImage extends StatelessWidget { final String src; final double? width; final double? height; const OptimizedImage({ Key? key, required this.src, this.width, this.height, }) : super(key: key); @override Widget build(BuildContext context) { return Image.network( src, width: width, height: height, loadingBuilder: (context, child, loadingProgress) { if (loadingProgress == null) return child; return Center( child: CircularProgressIndicator( value: loadingProgress.expectedTotalBytes != null ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes! : null, ), ); }, errorBuilder: (context, error, stackTrace) { return Container( width: width, height: height, color: Colors.grey[200], child: Icon(Icons.error), ); }, ); } } 

六、PWA 支持

1. 配置 manifest.json

{ "name": "Flutter Web App", "short_name": "FlutterApp", "description": "A Flutter Web application", "start_url": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#4285f4", "icons": [ { "src": "icons/Icon-192.png", "sizes": "192x192", "type": "image/png" }, { "src": "icons/Icon-512.png", "sizes": "512x512", "type": "image/png" } ] } 

2. 配置 service_worker.js

// service_worker.js const CACHE_NAME = 'flutter-app-cache'; const ASSETS = [ '/', '/index.html', '/manifest.json', '/icons/Icon-192.png', '/icons/Icon-512.png', ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { return cache.addAll(ASSETS); }) ); }); self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((response) => { return response || fetch(event.request); }) ); }); 

七、部署

1. 构建 Web 应用

# 开发模式 flutter build web # 生产模式(优化) flutter build web --release --web-renderer canvaskit # 生产模式(体积更小) flutter build web --release --web-renderer html 

2. 部署到静态网站托管

  • Firebase Hosting
  • Netlify
  • Vercel
  • GitHub Pages

Flutter Web 让跨平台开发变得简单优雅,就像好的设计一样自然。

#flutter #web #hybrid #cross-platform #frontend

Read more

【前端】前端面试题

【前端】前端面试题

前端面试题 闭包 1. 定义: 闭包(Closure) 是指一个函数能够访问并记住其外部作用域中的变量,即使外部函数已经执行完毕。闭包由两部分组成: * 一个函数(通常是内部函数)。 * 该函数被创建时所在的作用域(即外部函数的变量环境) functionouter(){let count =0;// 外部函数的变量functioninner(){ count++;// 内部函数访问外部变量 console.log(count);}return inner;}const counter =outer();counter();// 输出 1counter();// 输出 2 2. 闭包的核心原理 * 作用域链:函数在定义时,会记住自己的词法环境(即外部作用域)。当内部函数访问变量时,会沿着作用域链向上查找。 * 变量持久化:闭包使得外部函数的变量不会被垃圾回收,因为内部函数仍持有对它们的引用 3. 闭包的常见用途 3.1 私有变量封装 通过闭包隐藏内部变量,

【技术干货】用 Claude 4.6 直接“写”出可上线的前端 UI:从画布工具到代码工作流的升级思路

【技术干货】用 Claude 4.6 直接“写”出可上线的前端 UI:从画布工具到代码工作流的升级思路

摘要 本文从 Google Stitch 热度切入,对比“AI 画布式 UI 生成”与“代码内 UI 生成”两种路径,系统拆解如何用 Claude 4.6 + 前端设计规则,在真实代码库中迭代出可上线的 UI。附完整 Python API 调用示例与提示词模板,并结合多模型平台薛定猫 AI 的接入方式,帮助前端/全栈开发者把 AI UI 生成直接融入开发流水线。 一、背景:从“好看截图”到“可上线 UI” 当前 AI UI 方向大致两类路径: 1. 画布式设计工具 代表:Google Stitch

别再用 Electron 了!教你用 WebView2 实现 3MB 极致轻量化 Web 打包方案(附神器)

别再用 Electron 了!教你用 WebView2 实现 3MB 极致轻量化 Web 打包方案(附神器)

文章摘要:         你还在忍受 Electron 打包后动辄 100MB+ 的体积吗?你还在为本地 HTML 跨域(CORS)、源码保护、机器码授权而头秃吗?本文将带你体验微软新一代 WebView2 技术,并分享一款支持实时预览、全全局拖拽交互的打包神器。3MB 体积,1.5GB 大文件秒开,彻底解放前端生产力! 😱 为什么 2026 年了,我们还要逃离 Electron? 做前端桌面化开发,Electron 确实是老大哥,但它的缺点和优点一样明显: * 太胖了: 一个最简单的 Hello World,打包出来都要 150MB 起步。 * 太吃内存: 每个窗口都是一个 Chrome 进程,老爷机直接卡死。 * 开发繁琐: 想要实现“老板键”、“机器码授权”、“关机重启”,需要写大量的

基于.Net的Web API 控制器及方法相关注解属性

文章目录 * 1. 路由与 HTTP 方法 (`Microsoft.AspNetCore.Mvc` 命名空间) * 2. 参数绑定源 (`Microsoft.AspNetCore.Mvc` 命名空间) * 3. 响应类型与格式 (`Microsoft.AspNetCore.Mvc` 命名空间) * 4. 授权与认证 (`Microsoft.AspNetCore.Authorization` 命名空间) * 5. Swagger/OpenAPI 文档增强 (`Swashbuckle.AspNetCore.Annotations` 或 `Microsoft.AspNetCore.Mvc`) 这些属性主要用于定义 API 的路由、HTTP 方法、参数绑定、响应类型、授权、Swagger 文档等,通常位于控制器类或 Action