(译)Flutter 最佳实践

中文原文:https://github.com/sisterAn/blog/issues/78,英文原文:https://medium.com/flutter-community/flutter-best-practices-and-tips-7c2782c9ebb5

遵循最佳实践来提高代码质量和工作效率

最佳实践是一个领域可以接受的专业标准,对于任何编程语言来说,提高代码质量、可读性、可维护性和健壮性都非常重要。

让我们探索一些设计和开发Flutter应用程序的最佳实践。

1. 命名规则

class 、 enum 、 typedef 和 extension 应采用驼峰命名 UpperCamelCase 规则。

class MainScreen { ... }
enum MainItem { .. }
typedef Predicate<T> = bool Function(T value);
extension MyList<T> on List<T> { ... }

类库、包、目录、以及源码文件都应使用带下划线的小写命名 lowercase_with_underscores

library firebase_dynamic_links;
import 'socket/socket_manager.dart';

变量、常量、参数和命名参数应都应使用小写字母开头的驼峰命名 lowerCamelCase

var item;
const bookPrice = 3.14;
final urlScheme = RegExp('^([a-z]+):');
void sum(int bookPrice) {
  // ...
}

2. lib中的文件使用相对路径导入

当同时使用相对和绝对导入时,从两种不同的方式导入同一类时,可能会造成混乱。为了避免这种情况,我们应该对 lib/ 文件夹中的文件使用相对路径导入

// Don't
import 'package:demo/src/utils/dialog_utils.dart';


// Do
import '../../../utils/dialog_utils.dart';

3. 指定变量类型

当值的类型已知时,请务必指定成员的类型,尽可能避免使用 var

//Don't
var item = 10;
final car = Car();
const timeOut = 2000;


//Do
int item = 10;
final Car bar = Car();
String name = 'john';
const int timeOut = 20;

4. 避免使用 as 作类型转换,应使用 is 运算符

通常,如果无法进行强制转换,使用 as 强制转换将会引发异常,为了避免异常,可以使用 is

//Don't
(item as Animal).name = 'Lion';


//Do
if (item is Animal)
  item.name = 'Lion';

5. 使用 if 条件代替条件表达式

很多时候,我们需要根据条件渲染 Widget ,如果在条件表达式在任何情况下都返回 null 时,那么我们应该仅仅使用 if 条件

//Don't
Widget getText(BuildContext context) {
  return Row(
    children: [
      Text("Hello"),
      Platform.isAndroid ? Text("Android") : null,
      Platform.isAndroid ? Text("Android") : SizeBox(),
      Platform.isAndroid ? Text("Android") : Container(),
    ]
  );
}


//Do
Widget getText(BuildContext context) {
  return Row(
      children: 
      [
        Text("Hello"), 
        if (Platform.isAndroid) Text("Android")
      ]
  );
}

6. 使用 ?? 和 ?. 操作符

优先使用 ?? (如果为 null ) 和 ?. (可识别空值)运算符,而不是条件表达式中 null 检查

//Don't
v = a == null ? b : a;

//Do
v = a ?? b;


//Don't
v = a == null ? null : a.b;

//Do
v = a?.b;

7. 使用 spread 集合

当现有项目已经存储在另一个集合中时,spread 集合语法将使代码更简单

//Don't
var y = [4,5,6];
var x = [1,2];
x.addAll(y);


//Do
var y = [4,5,6];
var x = [1,2,...y];

8. 使用级联运算符

如果我们不想对同一对象执行一系列操作,则应使用级联运算符

// Don't
var path = Path();
path.lineTo(0, size.height);
path.lineTo(size.width, size.height);
path.lineTo(size.width, 0);
path.close();  


// Do
var path = Path()
..lineTo(0, size.height)
..lineTo(size.width, size.height)
..lineTo(size.width, 0)
..close();

9. 使用原始字符串

原始字符串可用于避免转义字符带来的困扰

//Don't
var s = 'This is demo string \\ and \$';


//Do
var s = r'This is demo string \ and $';

10. 不要显式初始化变量 null

在 Dart 中,如果未指定变量的值,则变量会自动初始化为 null ,因此添加 null 是多余且不需要的

//Don't
int _item = null;


//Do
int _item;

11. 使用表达式函数体

对于仅包含一个表达式的函数,可以使用表达式函数

//Don't
get width {
  return right - left;
}
Widget getProgressBar() {
  return CircularProgressIndicator(
    valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
  );
}


//Do
get width => right - left;
Widget getProgressBar() => CircularProgressIndicator(
      valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
    );

12. 避免调用 print()

print() 和 debugPrint() 均用于打印日志到控制台,如果你使用 print() 并且一次输出太多内容,Android 有时会丢弃一些日志行,为了避免这种情况,请使用 debugPrint()

13. 拆分 Widget

当调用 setState() ,所有后代 Widget 都将重建,因此,将 Widget 拆分为小的 Widget ,在真正需要改变的 Widget 上调用 setState()

Scaffold(
  appBar: CustomAppBar(title: "Verify Code"), // Sub Widget
  body: Container(
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        TimerView( // Sub Widget
            key: _timerKey,
            resendClick: () {})
      ],
    ),
  ),
)

14. 使用 ListView.builder 构建长列表

当使用无限列表或者非常大的列表时,通常建议使用 ListView.builder 以提高性能。

默认的 ListView 构造函数一次生成整个列表,ListView.builder 创建一个惰性列表,当用户向下滚动列表时,Flutter 会按需构建 Widget

15. 在 Widget 中使用 const

当 setState 调用时不会改变的 Widget ,我们应该将其定义为常量,这将阻止 Widget 重建,从而提高性能

Container(
      padding: const EdgeInsets.only(top: 10),
      color: Colors.black,
      child: const Center(
        child: const Text(
          "No Data found",
          style: const TextStyle(fontSize: 30, fontWeight: FontWeight.w800),
        ),
      ),
    );

我希望这些能给你一些见识,使你的 Flutter 代码更具可读性,同时也可以提高应用程序的性能。

编码愉快!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注