Skip to content

代码片段

Flu CLI VSCode 扩展内置了 20+ 个 Dart 代码片段,帮助你快速生成常用代码。

使用方法

  1. .dart 文件中输入片段前缀
  2. Tab 键展开
  3. 使用 Tab 在占位符间跳转
  4. 完成编辑

UI 组件片段

stWidget - StatefulWidget

前缀: stWidget

生成代码:

dart
class MyWidget extends StatefulWidget {
  const MyWidget({Key? key}) : super(key: key);

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

使用场景: 创建有状态的组件

lessWidget - StatelessWidget

前缀: lessWidget

生成代码:

dart
class MyWidget extends StatelessWidget {
  const MyWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

使用场景: 创建无状态的组件

stPage - StatefulWidget + ViewModel

前缀: stPage

生成代码:

dart
class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late final HomeViewModel _viewModel;

  @override
  void initState() {
    super.initState();
    _viewModel = HomeViewModel();
  }

  @override
  void dispose() {
    _viewModel.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Container(),
    );
  }
}

使用场景: 创建带 ViewModel 的页面

lessPage - StatelessWidget + ViewModel

前缀: lessPage

生成代码:

dart
class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Container(),
    );
  }
}

使用场景: 创建简单的页面

listPage - 列表页面

前缀: listPage

生成代码:

dart
class UserListPage extends StatefulWidget {
  const UserListPage({Key? key}) : super(key: key);

  @override
  State<UserListPage> createState() => _UserListPageState();
}

class _UserListPageState extends State<UserListPage> {
  late final UserListViewModel _viewModel;

  @override
  void initState() {
    super.initState();
    _viewModel = UserListViewModel();
    _viewModel.loadData();
  }

  @override
  void dispose() {
    _viewModel.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('User List'),
      ),
      body: RefreshIndicator(
        onRefresh: _viewModel.refresh,
        child: ListView.builder(
          itemCount: _viewModel.items.length,
          itemBuilder: (context, index) {
            final item = _viewModel.items[index];
            return ListTile(
              title: Text(item.toString()),
            );
          },
        ),
      ),
    );
  }
}

使用场景: 创建列表页面,带下拉刷新

逻辑层片段

viewmodel - 基础 ViewModel

前缀: viewmodel

生成代码:

dart
import 'package:flutter/foundation.dart';

class HomeViewModel extends ChangeNotifier {
  // 状态
  bool _isLoading = false;
  bool get isLoading => _isLoading;

  // 初始化
  Future<void> init() async {
    // TODO: 初始化逻辑
  }

  // 业务逻辑
  Future<void> loadData() async {
    _isLoading = true;
    notifyListeners();

    try {
      // TODO: 加载数据
    } catch (e) {
      debugPrint('Error: $e');
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  @override
  void dispose() {
    // TODO: 清理资源
    super.dispose();
  }
}

使用场景: 创建 ViewModel 类

listViewModel - 列表 ViewModel

前缀: listViewModel

生成代码:

dart
import 'package:flutter/foundation.dart';

class UserListViewModel extends ChangeNotifier {
  // 状态
  bool _isLoading = false;
  bool get isLoading => _isLoading;

  List<dynamic> _items = [];
  List<dynamic> get items => _items;

  int _page = 1;
  bool _hasMore = true;

  // 加载数据
  Future<void> loadData() async {
    if (_isLoading || !_hasMore) return;

    _isLoading = true;
    notifyListeners();

    try {
      // TODO: 加载数据
      // final data = await service.getList(page: _page);
      // _items.addAll(data);
      // _hasMore = data.isNotEmpty;
      // _page++;
    } catch (e) {
      debugPrint('Error: $e');
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  // 刷新
  Future<void> refresh() async {
    _page = 1;
    _hasMore = true;
    _items.clear();
    await loadData();
  }

  @override
  void dispose() {
    super.dispose();
  }
}

使用场景: 创建列表 ViewModel,带分页和刷新

model - 数据模型

前缀: model

生成代码:

dart
class UserModel {
  final String id;
  final String name;

  UserModel({
    required this.id,
    required this.name,
  });

  // 从 JSON 创建
  factory UserModel.fromJson(Map<String, dynamic> json) {
    return UserModel(
      id: json['id'] as String,
      name: json['name'] as String,
    );
  }

  // 转换为 JSON
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
    };
  }

  // 复制并修改
  UserModel copyWith({
    String? id,
    String? name,
  }) {
    return UserModel(
      id: id ?? this.id,
      name: name ?? this.name,
    );
  }
}

使用场景: 创建数据模型类

service - 服务类

前缀: service

生成代码:

dart
import 'package:http/http.dart' as http;
import 'dart:convert';

class UserService {
  final String baseUrl = 'https://api.example.com';

  // GET 请求
  Future<Map<String, dynamic>> getUser(String id) async {
    final response = await http.get(
      Uri.parse('$baseUrl/users/$id'),
    );

    if (response.statusCode == 200) {
      return json.decode(response.body);
    } else {
      throw Exception('Failed to load user');
    }
  }

  // POST 请求
  Future<Map<String, dynamic>> createUser(Map<String, dynamic> data) async {
    final response = await http.post(
      Uri.parse('$baseUrl/users'),
      headers: {'Content-Type': 'application/json'},
      body: json.encode(data),
    );

    if (response.statusCode == 201) {
      return json.decode(response.body);
    } else {
      throw Exception('Failed to create user');
    }
  }
}

使用场景: 创建 API 服务类

component - 通用组件类

前缀: component

生成代码:

dart
import 'package:flutter/material.dart';

class UserCard extends StatelessWidget {
  final String title;
  final VoidCallback? onTap;

  const UserCard({
    Key? key,
    required this.title,
    this.onTap,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Card(
      child: InkWell(
        onTap: onTap,
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Text(title),
        ),
      ),
    );
  }
}

使用场景: 创建可复用的组件

Provider 片段

providerPage - Provider 页面

前缀: providerPage

生成代码:

dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => HomeViewModel(),
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Home'),
        ),
        body: Consumer<HomeViewModel>(
          builder: (context, viewModel, child) {
            return Container();
          },
        ),
      ),
    );
  }
}

使用场景: 创建使用 Provider 的页面

consumer - Consumer Widget

前缀: consumer

生成代码:

dart
Consumer<HomeViewModel>(
  builder: (context, viewModel, child) {
    return Container();
  },
)

使用场景: 快速创建 Consumer

selector - Selector Widget

前缀: selector

生成代码:

dart
Selector<HomeViewModel, bool>(
  selector: (context, viewModel) => viewModel.isLoading,
  builder: (context, isLoading, child) {
    return Container();
  },
)

使用场景: 创建性能优化的 Selector

GetX 片段

getxPage - GetX 页面

前缀: getxPage

生成代码:

dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final controller = Get.put(HomeController());

    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Obx(() => Container()),
    );
  }
}

使用场景: 创建使用 GetX 的页面

getxController - GetX Controller

前缀: getxController

生成代码:

dart
import 'package:get/get.dart';

class HomeController extends GetxController {
  // 响应式状态
  final _isLoading = false.obs;
  bool get isLoading => _isLoading.value;

  @override
  void onInit() {
    super.onInit();
    // TODO: 初始化
  }

  // 业务逻辑
  Future<void> loadData() async {
    _isLoading.value = true;

    try {
      // TODO: 加载数据
    } catch (e) {
      print('Error: $e');
    } finally {
      _isLoading.value = false;
    }
  }

  @override
  void onClose() {
    // TODO: 清理资源
    super.onClose();
  }
}

使用场景: 创建 GetX Controller

工具类片段

singleton - 单例模式

前缀: singleton

生成代码:

dart
class AppConfig {
  AppConfig._();

  static final AppConfig _instance = AppConfig._();
  static AppConfig get instance => _instance;

  // 属性和方法
}

使用场景: 创建单例类

future - Future 方法

前缀: future

生成代码:

dart
Future<void> methodName() async {
  try {
    // TODO: 异步操作
  } catch (e) {
    debugPrint('Error: $e');
  }
}

使用场景: 快速创建异步方法

stream - Stream 方法

前缀: stream

生成代码:

dart
Stream<int> countStream() async* {
  for (int i = 0; i < 10; i++) {
    await Future.delayed(const Duration(seconds: 1));
    yield i;
  }
}

使用场景: 创建 Stream

自定义片段

你可以创建自己的代码片段:

步骤 1:打开片段设置

  1. 打开命令面板(Cmd+Shift+P / Ctrl+Shift+P
  2. 输入 Preferences: Configure User Snippets
  3. 选择 dart.json

步骤 2:添加片段

json
{
    "My Custom Widget": {
        "prefix": "mywidget",
        "body": [
            "class ${1:MyWidget} extends StatelessWidget {",
            "  const ${1:MyWidget}({Key? key}) : super(key: key);",
            "",
            "  @override",
            "  Widget build(BuildContext context) {",
            "    return ${2:Container}();",
            "  }",
            "}"
        ],
        "description": "My custom widget template"
    }
}

步骤 3:使用片段

.dart 文件中输入 mywidget,按 Tab 展开。

片段变量

片段支持以下变量:

变量说明示例
${1:placeholder}第一个占位符${1:MyWidget}
${2:placeholder}第二个占位符${2:Container}
$1引用第一个占位符class $1
$TM_FILENAME_BASE文件名(无扩展名)home_page
$TM_DIRECTORY目录名pages

最佳实践

1. 使用一致的命名

  • Page 片段:xxxPage
  • ViewModel 片段:xxxViewModel
  • Widget 片段:xxxWidget

2. 合理使用占位符

json
{
    "body": [
        "class ${1:MyWidget} extends StatelessWidget {",
        "  const ${1:MyWidget}({Key? key}) : super(key: key);",
        "  // 使用 $1 引用第一个占位符",
        "}"
    ]
}

3. 添加描述

json
{
    "description": "Create a stateless widget with custom styling"
}

4. 分组管理

将相关片段放在一起:

json
{
  "// UI Components": {},
  "StatefulWidget": { ... },
  "StatelessWidget": { ... },

  "// ViewModels": {},
  "ViewModel": { ... },
  "ListViewModel": { ... }
}

常见问题

片段不生效?

  1. 确认文件类型是 .dart
  2. 检查片段前缀是否正确
  3. 尝试重启 VSCode

如何查看所有片段?

  1. 打开命令面板(Cmd+Shift+P / Ctrl+Shift+P
  2. 输入 Insert Snippet
  3. 查看可用片段列表

片段冲突怎么办?

如果多个扩展提供相同前缀的片段:

  1. 输入前缀后会显示多个选项
  2. 使用方向键选择需要的片段
  3. TabEnter 展开

如何分享片段?

  1. 导出 dart.json 文件
  2. 分享给团队成员
  3. 团队成员复制到自己的片段文件中

下一步

相关链接

Released under the MIT License.