Адрес склада:GitHub.com/Се Йези/Приложение…
скажи это прямо
Привет, давно не виделись, друзья, в этот раз привожу практическую статью по flutter + getx.
на основеgetxРеализовано совершенно новоеflutter getxШаблон, подходящий для разработки средних и крупных проектов.
- 💥
flutterпоследняя версия нулевого сейфа - 🍀
viewа также逻辑полностью развязанный - ⚡
viewа такжеstateавтоматический ответ - 📦
dio,shared_preferencesПакеты такого распространенного модуля - Выйди
contextизменять
окружающая обстановка
Flutter 2.2.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision b22742018b (3 weeks ago) • 2021-05-14 19:12:57 -0700
Engine • revision a9d88a4d18
Tools • Dart 2.13.0
подразделение каталога lib
common
Этот каталог используется для хранения общих модулей и их переменных, таких какcolors,langs,valuesи т.д., например:
├── colors
│ └── colors.dart
├── langs
│ ├── en_US.dart
│ ├── translation_service.dart
│ └── zh_Hans.dart
└── values
├── cache.dart
├── storage.dart
└── values.dart
components
В этом каталоге в основном хранятся компоненты объявлений верхнего уровня, такие какappbar,scaffold,dialogд., например:
├── components.dart
├── custom_appbar.dart
└── custom_scaffold.dart
pages
В этом каталоге в основном хранятся файлы подкачки, например:
Примечание. Каждый элемент представляет собой папку.
├── Index
├── home
├── login
├── notfound
├── proxy
└── splash
router
Этот каталог является файлом маршрутизации, и соглашение о маршрутизации этого шаблона命名路由, является фиксированным каталогом, структура каталогов выглядит следующим образом:
├── app_pages.dart
└── app_routes.dart
services
Этот каталог используется для храненияAPI,Например:
├── services.dart
└── user.dart // 关于用户的API
utils
Этот каталог используется для хранения некоторых модулей инструментов, таких какrequest,local_storageд., например:
├── authentication.dart
├── local_storage.dart
├── request.dart
├── screen_device.dart
└── utils.dart
спецификация разработки
Когда вам нужно создать новую страницу, вам необходимо выполнить следующие шаги:
Предположим, теперь мы хотим создать
Homeстраница.
- существует
pagesновый каталогhomeсодержание:
// pages
$ mkdir home
$ cd home
- существует
homeВ каталоге создайте следующие четыре файла:
-
home_view.dart: Вид (используется для реализации макета страницы) -
home_contrller.dart: Контроллер (используется для реализации бизнес-логики) -
home_binding: привязка контроллера (используется для привязкиcontrollerприбытьview) -
home_model: модель данных (используется для согласования модели данных)
Примечание. Это необходимо делать каждый раз при создании страницы с именем '页面名_key' такая форма.
При создании страницы оглавление должно выглядеть так👇:
// home
.
├── home.binding.dart
├── home_controller.dart
├── home_model.dart
└── home_view.dart
- прибыть
routerДобавьте соответствующий маршрут в папку:
// app_routes.dart
part of 'app_pages.dart';
abstract class AppRoutes {
...
static const Home = '/home';
...
}
// app_pages.dart
class AppPages {
static final routes = [
...
GetPage(
name: AppRoutes.Home,
page: () => HomePage(),
binding: HomeBinding(),
),
...
];
}
Выполнив вышеуказанные шаги, вы можете начать счастливо развиваться.
государственное управление
contrllerЗдесь мы реализуем бизнес-логику, почему мы отделяем бизнес-логику от представлений? потому чтоflutterКод в стиле спагетти слишком сложно поддерживать, иflutterМакет и стиль страницы отвратительно писать вместе, плюс код бизнес-логики, его слишком сложно поддерживать, и если мы хотим иметь состояние, наша страница должна наследоваться отstateful widget, потеря производительности слишком серьезна.
Поэтому мы используемgetxкоторый предоставилcontroller, чтобы отделить нашу бизнес-логику от наших представлений.
стандартcontrllerЭто выглядит так:
class HomeController extends GetxController {
final count = 0.obs;
@override
void onInit() {
super.onInit();
}
@override
void onReady() {}
@override
void onClose() {}
void increment() => count.value++;
}
Когда нам нужна реактивная переменная, мы просто добавляем переменную после переменной.obs,Например:
final name = ''.obs;
final isLogged = false.obs;
final count = 0.obs;
final balance = 0.0.obs;
final number = 0.obs;
final items = <String>[].obs;
final myMap = <String, int>{}.obs;
// 甚至自定义类 - 可以是任何类
final user = User().obs;
Стоит отметить, что поскольку сейчас
flutterимеютnull-safety, поэтому нам лучше дать реактивной переменной начальное значение.
когда мыcontrollerПредставления автоматически обновляют визуализацию при обновлении реактивных переменных.
Но на самом деле можно и не определять такого рода реактивную переменную, например, мы можем сделать так:
class HomeController extends GetxController {
int count = 0;
@override
void onInit() {
super.onInit();
}
@override
void onReady() {}
@override
void onClose() {}
void increment() {
count++;
update();
}
}
такой и.obsЕдинственная разница в том, что нам нужно вручную вызватьupdate()Обновить изменения состояния, подобные этомуviewбыть способнымcountКогда он изменится, получите уведомление для повторного рендеринга.
Мы должны поместить инициирующий запрос вonInitВ хуке, например, при входе на страницу заказа мы должны получить информацию о заказе, как и вstateful wdigetвнутриinitКак крючки.
Посмотреть
Во-первых, вам нужно поставить свойclassунаследовано отGetxView<T>(T — ваш контроллер), например:
class HomePage extends GetView<HomeController> {
HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}
GetxView<HomeController>автоматически поможет вамControllerвводить вview, вы можете просто понять, что он автоматически выполняет следующие шаги для вас
final controller = Get.find<HomeController>();
не нужно беспокоитьсяGetxView<T>производительность, так как он просто наследуется отStateless Widget, помните, что сgetxтебе не нужноStateful Widget
когда мы хотим связатьcontrollerпеременная, мы договорились о двух методах:
Obx(()=>)
если ваша переменная.obs, то используемObx(()=>), который автоматически обновляется при изменении переменнойview,Например:
// home_contrller
class HomeController extends GetxController {
final count = 0.obs;
@override
void onInit() {
super.onInit();
}
@override
void onReady() {}
@override
void onClose() {}
void increment() => count.value++;
}
существуетviewвнутри использованиеObx(()=>)связыватьcount:
// home_view
class HomePage extends GetView<HomeController> {
HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Obx(() => Center(child: Text(controller.count.toString()))),
),
);
}
}
GetBuilder<T>
если ваша переменная не.obs, то используемGetBuilder<T>,Например:
class HomeController extends GetxController {
int count = 0;
@override
void onInit() {
super.onInit();
}
@override
void onReady() {}
@override
void onClose() {}
void increment() {
count++;
update();
}
}
существуетviewвнутри использованиеGetBuilder<T>связыватьcount:
class HomePage extends GetView<HomeController> {
HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BaseScaffold(
appBar: MyAppBar(
centerTitle: true,
title: MyTitle('首页'),
leadingType: AppBarBackType.None,
),
body: Container(
child: GetBuilder<HomeController>(builder: (_) {
return Center(child: Text(controller.count.toString()));
}),
),
);
}
}
фактическиgetxтакже предоставляет другиеrender function, но чтобы уменьшить умственную нагрузку и сложность, мы просто используем эти два.
управление маршрутом
Здесь мы используемgetxПредоставляет именованную маршрутизацию, если вы узналиvue, то почти нет затрат на обучение.
Предположим, теперь мы добавляем страницу с именемList, то нам нужноrouterПапка для его настройки:
// app_routes.dart
part of 'app_pages.dart';
abstract class AppRoutes {
...
static const List = '/list';
...
}
// app_pages.dart
class AppPages {
static final routes = [
...
GetPage(
name: AppRoutes.Home,
page: () => ListPage(),
binding: ListBinding(),
),
...
];
}
этоListСоответствующим предположением является список заказов.Когда мы нажимаем на заказ в списке, мы обычно попадаем на страницу сведений о заказе, поэтому в это время мы должны добавить еще одну страницу сведений:
// app_routes.dart
part of 'app_pages.dart';
abstract class AppRoutes {
...
static const List = '/list';
static const Detaul = '/detail';
...
}
// app_pages.dart
class AppPages {
static final routes = [
...
GetPage(
name: AppRoutes.Home,
page: () => ListPage(),
binding: ListBinding(),
children: [
GetPage(
name: AppRoutes.Detail,
page: () => DetailPage(),
binding: DetailBinding(),
),
],
),
...
];
}
Поскольку страница сведений и страница списка имеют отношение приоритета, мы можем поместитьDetailстраница, поставитьListизchildrenНиже, конечно, можно поступить иначе.
Когда мы используем:
Get.toNamed('/list/detail');
Другие хуки маршрутизации:
Просмотрите и удалите предыдущую страницу:
Get.offNamed("/NextScreen");
Просмотрите и удалите все предыдущие страницы:
Get.offAllNamed("/NextScreen");
Параметры передачи:
Get.toNamed("/NextScreen", arguments: {id: 'xxx'});
Тип параметра может быть строкой, картой, списком или даже экземпляром класса.
Параметры приобретения:
print(Get.arguments);
// print out: `{id: 'xxx'}`
использоватьgetxмаршрутизация имеет очень приятное преимущество, что она去context化из. Помните, когда мы былиcontextДоминировать над страхом? имеютgetx, он перестанет существовать.
использоватьmonia-cliразвивать
Мы очень счастливы, могутflutter-getx-templateПрисоединяйсяmonia-cli.
использоватьmonia-cliновыйflutterпроект:
monia create <project-name>
➜ Desktop monia create flutter_demo
? Which framework do you want to create Flutter
? Which flutter version do you want to create null-safety
? Please input your project description description
? Please input project version 1.0.0
✨ Creating project in /Users/xieyezi/Desktop/flutter_demo.
🗃 Initializing git repository....
.......
⠏ Download template from monia git repository... This might take a while....
🎉 Successfully created project flutter_demo.
👉 Get started with the following commands:
$ cd flutter_demo
$ flutter run
_ _ _
_ __ ___ ___ _ __ (_) __ _ ___| (_)
| '_ ` _ \ / _ \| '_ \| |/ _` |_____ / __| | |
| | | | | | (_) | | | | | (_| |_____| (__| | |
|_| |_| |_|\___/|_| |_|_|\__,_| \___|_|_|
Не только это,monia-cliТакже обеспечивает быстрое созданиеflutter getxфункция страницы.
Предположим, теперь вы хотите сгенерироватьorder_sendingновая страница, вам просто нужноpagesВойдите в следующий каталог:
monia init order_sending
➜ pages monia init order_sending
✨ Generate page in /Users/xieyezi/Desktop/flutter_demo/lib/pages/order_sending.
⠋ Generating, it's will not be wait long...
generate order_sending lib success.
generate /Users/xieyezi/Desktop/flutter_demo/lib/pages/order_sending/order_sending_view.dart file success.
generate /Users/xieyezi/Desktop/flutter_demo/lib/pages/order_sending/order_sending_controller.dart file success.
generate /Users/xieyezi/Desktop/flutter_demo/lib/pages/order_sending/order_sending_binding.dart file success.
🎉 Successfully generate page order_sending.
Плагин vscode
moniaтакже обеспечиваетvscodeПлагин:monia-vscode-extension
Нажмите в левом нижнем углуmonia-generateтекстовая кнопка, введитеpageName, ты сможешьpagesСоздайте новый в каталогеflutter getx page:
Официальная ссылка
государственное управление управление маршрутом управление зависимостями