最佳實踐是一個領域能夠接受的專業標準,對於任何編程語言來講,提升代碼質量、可讀性、可維護性和健壯性都很是重要。前端
讓咱們探索一些設計和開發Flutter應用程序的最佳實踐。web
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
app
//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
socket
//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
代碼更具可讀性,同時也能夠提升應用程序的性能。
編碼愉快!
最後
![](http://static.javashuo.com/static/loading.gif)
本文分享自微信公衆號 - 前端瓶子君(pinzi_com)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。