Flutter
ไมโครเฟรมเวิร์ก
สำหรับแอปสมัยใหม่
Nylo ให้ทุกโปรเจกต์มีรากฐานที่มั่นคงเหมือนกัน — การกำหนดเส้นทาง สถานะ เครือข่าย ฟอร์ม และการยืนยันตัวตน — คุณจึงเริ่มที่ฟีเจอร์แรก แทนที่จะเป็นไฟล์แรก
dart pub global activate nylo_installer
ทุกสิ่งที่คุณต้องการสำหรับการสร้าง
หกเสาหลัก หนึ่งแบบแผน แต่ละส่วนมาพร้อมตัวสร้างของ Metro ค่าเริ่มต้นที่สมเหตุสมผล และทางออกสำรอง — ข้างใต้ก็ยังเป็น Flutter ล้วน ๆ
ระบบเส้นทาง
เส้นทางแบบประกาศ พร้อมการ์ด พารามิเตอร์ที่มีชนิด ทรานซิชัน และ deep linking
การจัดการสถานะ
สถานะแบบรีแอกทีฟ พร้อมคอนโทรลเลอร์ ฮุกวงจรชีวิต และการบันทึกข้อมูลที่ไม่ยุ่งยาก
เครือข่าย
คลาสบริการ API พร้อมการถอดรหัสโมเดลอัตโนมัติและตัวดักคำขอ
ฟอร์ม
ประกาศฟิลด์เพียงครั้งเดียว — การตรวจสอบ การแปลงชนิด และการผูกข้อมูลมาพร้อมกัน
การยืนยันตัวตน
การจัดการเซสชัน การเก็บโทเค็น และการ์ดเส้นทาง โดยไม่ต้องตั้งค่าเฉพาะทาง
Metro CLI
สร้างหน้า โมเดล คอนโทรลเลอร์ ฟอร์ม และธีม ด้วยคำสั่งเดียว
สร้างทุกอย่างจากเทอร์มินัล
Metro สร้างหน้า โมเดล คอนโทรลเลอร์ วิดเจ็ต และอื่น ๆ โดยเชื่อมเข้ากับเราเตอร์และโครงสร้างโฟลเดอร์ของคุณ ไม่ใช่แค่ทิ้งไว้มุมใดมุมหนึ่ง
class ApiService extends NyApiService {
@override
String get baseUrl => "https://api.example.com/v1";
Future<List<Post>> posts() async {
return await network(
request: (request) => request.get("/posts"),
);
}
}
// Usage in your page
final posts = await api<ApiService>((request) => request.posts());
การเชื่อมต่อ API อย่างง่ายดาย
เขียนบริการ API ที่สะอาดและดูแลง่าย พร้อมการแปลง JSON อัตโนมัติ การจัดการข้อผิดพลาด และตัวดักคำขอ — โดยไม่ต้องมีโค้ด Dio ซ้ำ ๆ ในหน้าของคุณ
เรียนรู้เพิ่มเติมเกี่ยวกับเครือข่ายดูในโค้ดที่คุณจะเขียนจริง
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(DiscoverPage.path);
router.add(LoginPage.path,
transitionType: TransitionType.bottomToTop());
router.add(ProfilePage.path,
routeGuard: [
AuthGuard()
]
);
});
สร้างเส้นทาง อินเทอร์เฟซ และหน้า UI ที่ซับซ้อนสำหรับแอปพลิเคชัน Flutter ของคุณ
เรียนรู้เพิ่มเติมยืนยันตัวตนผู้ใช้
String userToken = "eyJhbG123...";
await Auth.authenticate(data: {"token": userToken});
ตอนนี้ เมื่อผู้ใช้ของคุณเปิดแอป พวกเขาจะได้รับการยืนยันตัวตนแล้ว
final userData = Auth.data();
// {"token": "eyJhbG123..."}
bool isAuthenticated = await Auth.isAuthenticated();
// true
หากคุณได้ตั้งค่า authenticatedRoute ในเราเตอร์ของคุณ หน้านี้จะถูกแสดงเมื่อผู้ใช้เปิดแอปอีกครั้ง
appRouter() => nyRoutes((router) {
...
router.add(LandingPage.path).initialRoute();
router.add(DashboardPage.path).authenticatedRoute();
// overrides the initial route when a user is authenticated
ออกจากระบบผู้ใช้
await Auth.logout();
ยืนยันตัวตนผู้ใช้ในแอปพลิเคชัน Flutter ของคุณ
เรียนรู้เพิ่มเติมสร้างฟอร์ม
metro make:form RegisterForm
แก้ไขฟอร์มของคุณ
class RegisterForm extends NyFormWidget {
RegisterForm({super.key, super.submitButton, super.onSubmit, super.onFailure});
// Add your fields here
@override
fields() => [
Field.capitalizeWords("name",
label: "Name",
validator: FormValidator.notEmpty(),
),
Field.email("email_address",
label: "Email",
validator: FormValidator.email()
),
Field.password("password",
label: "Password",
validator: FormValidator.password(),
),
];
static NyFormActions get actions => const NyFormActions("RegisterForm");
}
ใช้ฟอร์มของคุณในวิดเจ็ต
@override
Widget build(BuildContext context) {
return Scaffold(
body: RegisterForm(
submitButton: Button.primary(text: "Submit"),
onSubmit: (data) {
printInfo(data);
},
),
);
}
จัดการ ตรวจสอบ และส่งข้อมูลทั้งหมดในที่เดียวด้วย Nylo Forms
เรียนรู้เพิ่มเติมสร้างวิดเจ็ตที่จัดการสถานะ
metro make:stateful_widget CartIcon
class _CartIconState extends NyState<CartIcon> {
...
@override
Map<String, Function> get stateActions => {
"clear_cart": () {
_items = 0;
},
...
};
@override
Widget view(BuildContext context) {
return Container(child: Text("Items in cart: ${_items}"));
}
}
Use CartIcon.action("clear_cart")
Button.primary(text: "Add to cart",
onPressed: () {
CartIcon.action("clear_cart");
}
)
การจัดการสถานะที่ทรงพลังสำหรับวิดเจ็ตในแอปพลิเคชัน Flutter ของคุณ
เรียนรู้เพิ่มเติมสร้างเหตุการณ์ของคุณ
metro make:event Logout
class LogoutEvent implements NyEvent {
@override
final listeners = {
DefaultListener: DefaultListener(),
};
}
class DefaultListener extends NyListener {
@override
handle(dynamic event) async {
// logout user
await Auth.logout();
// redirect to home page
routeTo(HomePage.path,
navigationType: NavigationType.pushAndForgetAll
);
}
}
ส่งเหตุการณ์
MaterialButton(child: Text("Logout"),
onPressed: () {
event<LogoutEvent>();
},
)
ส่งเหตุการณ์และรับฟังเหตุการณ์ในแอปพลิเคชันของคุณ
เรียนรู้เพิ่มเติมกำหนดเวลาให้งานทำงานครั้งเดียว
Nylo.scheduleOnce("onboarding_info", () {
print("Perform code here to run once");
});
กำหนดเวลาให้งานทำงานครั้งเดียวหลังจากวันที่ระบุ
Nylo.scheduleOnceAfterDate("app_review_rating", () {
print("Perform code to run once after DateTime(2025, 04, 10)");
}, date: DateTime(2025, 04, 10));
กำหนดเวลาให้งานทำงานวันละครั้ง
Nylo.scheduleOnceDaily("free_daily_coins", () {
print("Perform code to run once daily");
});
กำหนดเวลาให้งานทำงานครั้งเดียวหรือรายวันในแอปพลิเคชัน Flutter ของคุณ
เรียนรู้เพิ่มเติมสร้างบริการ API
metro make:api_service User
class UserApiService extends NyApiService {
@override
String get baseUrl => getEnv("API_BASE_URL");
Future<User?> fetchUser(int id) async {
return await get<User>(
"/users/$id",
queryParameters: {"include": "profile"},
);
}
Future<User?> createUser(Map<String, dynamic> data) async {
return await post<User>("/users", data: data);
}
}
เรียกใช้ API จากหน้าของคุณ
User? user = await api<UserApiService>(
(request) => request.fetchUser(1),
);
บริการ API ที่สวยงาม พร้อมการแยกวิเคราะห์ JSON อัตโนมัติ แคช และตัวดักจับ
เรียนรู้เพิ่มเติมบันทึกข้อมูลอย่างปลอดภัย
// Save values to secure storage
await NyStorage.save("coins", 100);
await NyStorage.save("username", "Anthony");
await NyStorage.save("isPremium", true);
// Save with TTL (auto-expires)
await NyStorage.save("session", "abc123",
expiry: Duration(hours: 1),
);
อ่านพร้อมการแปลงชนิดข้อมูล
// Automatic type casting
String? username = await NyStorage.read("username");
int? coins = await NyStorage.read<int>("coins");
bool? isPremium = await NyStorage.read<bool>("isPremium");
// Delete a value
await NyStorage.delete("coins");
พื้นที่จัดเก็บภายในที่ปลอดภัย พร้อมการแปลงชนิดข้อมูล การหมดอายุ TTL และคอลเลกชัน
เรียนรู้เพิ่มเติมเพิ่มไฟล์ภาษาของคุณ
{
"welcome": "Welcome",
"greeting": "Hello {{name}}",
"navigation": {
"home": "Home",
"profile": "Profile"
}
}
แปลข้อความในวิดเจ็ตของคุณ
// Simple translation
Text("welcome".tr()) // "Welcome"
// With arguments
Text("greeting".tr(arguments: {"name": "Anthony"}))
// "Hello Anthony"
// Nested keys
Text("navigation.home".tr()) // "Home"
รองรับหลายภาษาด้วยไฟล์ JSON อาร์กิวเมนต์ และ RTL
เรียนรู้เพิ่มเติมสร้างศูนย์กลางการนำทาง
metro make:navigation_hub base
class _BaseNavigationHubState extends NavigationHub<BaseNavigationHub> {
NavigationHubLayout? layout = NavigationHubLayout.bottomNav();
@override
bool get maintainState => true;
_BaseNavigationHubState() : super(() async {
return {
0: NavigationTab(
title: "Home",
page: HomeTab(),
icon: Icon(Icons.home),
),
1: NavigationTab(
title: "Settings",
page: SettingsTab(),
icon: Icon(Icons.settings),
),
};
});
}
สลับเลย์เอาต์ได้ง่ายๆ
// Bottom navigation
NavigationHubLayout.bottomNav()
// Top navigation
NavigationHubLayout.topNav()
// Journey / wizard flow
NavigationHubLayout.journey()
สร้างแถบนำทางด้านล่าง แถบนำทางด้านบน หรือโฟลว์การเดินทาง พร้อมรักษาสถานะ
เรียนรู้เพิ่มเติมพัฒนาอย่างเปิดเผย ใช้งานจริงในโปรดักชัน
“ผมเพิ่งเริ่มใช้ Dart และเฟรมเวิร์กของคุณ — ซึ่งผมชอบมาก”
“Nylo คือเฟรมเวิร์กที่ดีที่สุดสำหรับ Flutter — ทำให้การพัฒนาเป็นเรื่องง่าย”
@higakijin
“เป็นเฟรมเวิร์กที่ดีที่สุดเท่าที่มีมา คุณภาพและฟีเจอร์ยอดเยี่ยม”
@2kulfi
“ทำให้งานง่ายขึ้นและใช้เวลาน้อยลง เยี่ยมมาก”
darkreader01
“เพิ่งค้นพบเฟรมเวิร์กนี้และประทับใจมาก ขอบคุณครับ”
@lepresk
“ชอบแนวคิดของเฟรมเวิร์กนี้มากจริง ๆ”
@Chrisvidal
“อยากขอบคุณพวกคุณสำหรับงานยอดเยี่ยมที่กำลังทำอยู่”
@youssefKadaouiAbbassi
“แค่อยากบอกว่าผมหลงรักเว็บไซต์ของ @nylo_dev!”
@esfoliante_txt
“สุดยอดมาก ทำได้ดีเยี่ยม!”
FireflyDaniel
แอป Flutter ตัวถัดไปของคุณเริ่มต้นด้วยคำสั่งเดียว
ฟรี ใช้สัญญาอนุญาต MIT และข้างใต้ก็ยังเป็น Flutter ล้วน ๆ
dart pub global activate nylo_installer