Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(译)Flutter 最佳实践 #78

Open
sisterAn opened this issue Oct 3, 2020 · 0 comments
Open

(译)Flutter 最佳实践 #78

sisterAn opened this issue Oct 3, 2020 · 0 comments

Comments

@sisterAn
Copy link
Owner

sisterAn commented Oct 3, 2020

来源:Kinjal Dhamat

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

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

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

1. 命名规则

classenumtypedefextension 应采用驼峰命名 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 代码更具可读性,同时也可以提高应用程序的性能。

编码愉快!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant