flutter mvvm 模式

作者: lzyprime | 来源:发表于2019-11-17 22:15 被阅读0次

lzyprime 博客

2020.01.16 更新

yesterday, 收到网友反馈,照抄如下内容不好用,希望我出个demo。 咋能不好用呢,下边这代码本身就可以当 demo 啊。于是老夫也照抄试了试,老夫也是一片爆红。。

老夫按 model -> viewModel -> view 的顺序往下写,结果 model 就出错了。原因很简单: rxdart 更新了!!, 原以为就算更新也不至于换接口这么频啊。好家伙,又低估他们了。

新版 rxdart 去掉了 Observable 类,相当于给原生 Stream 提供一组拓展函数。(详情可看https://pub.dev/packages/rxdart),所以 model 里的返回值直接是原生 Stream, 不用再套一层。 其他该怎么用还怎么用。

原文代码仍可用,注意插件版本号。

这是用最新插件写的demo,github 仓库: flutter_demos 分支: mvvm_demo

git clone -b mvvm_demo https://github.com/lzyprime/flutter_demos.git

另外,重新写一下做一下补充。 新文内容, 补充说明


原文内容

λ:

我的第一份flutter笔记,从选用那种架构模式开始。因为关于flutter 本身的 安装,构建UI 等等,比比皆是,除非疑难杂症,有必要鞋一份解决总结,其他的,官网和各大网站的手册和教材足够了。没必要功利到做个搬运工,从而赚取点击量

架构模式这种东西,跟你具体用什么语言、什么框架,关系不大。简单讲就是你怎么组织代码。便于逻辑清晰,更具条理。避免代码一整驼一整驼,甚至复制粘贴,全是重复、冗余代码。

mvc -> mvp -> mvvm, 不断演进与升级。了解一下分别是什么后,mvvm 的一大优势便是 viewmodel 双向绑定,任何一方的变动,都可以通知到另外一方。而另外两个,几乎是 单方主动请求

mvvm

mvvm.png

viewModel 作为 viewmodel 的中间者,处理view发出的请求,并在model数据等变化时,通知view 更新UI。

说起来很简单的样子。

flutter项目 mvvm

1. 添加插件:provider , rxdartpubspec.yaml 文件

pubspec.png

2. view, 构建UI,数据来源于viewModel

// file path : 'package:client/views/login_widget.dart'

import 'package:flutter/material.dart';

import 'package:client/view_models/login_view_model.dart'

class LoginWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final viewModel = Provider.of<LoginViewModel>(context); // 获取上层provider
    return Column(
      children: <Widget>[
        TextField(
          controller: viewModel.usernameController, // 方便viewModel 获取输入内容
        ),
        TextField(
          controller: viewModel.passwordController, // 方便viewModel 获取输入内容
        ),

        /// state 初始为 0,显示"登录" 字样;点击按钮后,加载过程值为 1;请求成功值为 2,显示对号
        FlatButton(
          child: viewModel.state == 0 
              ? Text("login")
              : (viewModel.state == 1
                  ? CircleAvatar(
                      backgroundColor: color,
                      child: CircularProgressIndicator(
                        backgroundColor: Colors.white,
                      ),
                      maxRadius: 10)
                  : Icon(
                      Icons.done,
                      color: Colors.white,
                    )),
          onPressed: viewModel.login,
        )
      ],
    );
  }
}

3. model, 请求和处理

// file path : package:client/models/login_model.dart


class LoginModel {
    // 建立 future 对象的 observable
    Observable login(dynamic data) => Observable.fromFuture(
        http.post('http://api_url', body: data)
    );
}

4. viewModel

// file path : 'package:client/view_models/login_view_model.dart'

import 'package:client/models/login_model.dart';

/// with ChangeNotifer : 通过 notifyListeners() 函数,可以通知本对象数据的正在使用者们。 如 state 变量,在改变后调用 notifyListeners(), UI根据值重新构建登录按钮显示内容

class LoginViewModel with ChangeNotifier {
  final _model = LoginModel(); // model, 网络请求等处理

  final usernameController = TextEditingController();
  final passwordController = TextEditingController();
  int state = 0;

  /// login 请求需要的数据
  get _data => {
    'username': usernameController.text,
    'password': passwordController.text
   };

  void login() =>_model.login(_data)
  .doOnListen((){state = 1; notifyListeners();}) // 请求过程,state = 1, 显示加载,通知UI
  .listen(// listen 接收两个参数,成功后的处理,失败后的处理。
      (res){ 
    state = res['result'] == 0 ? 2 : 0; // 登录成功时,回包中的result 字段为 0;
    notifyListeners();
  }, (_){ // 请求出错
      state = 0;
      notifyListeners();
  });
}

main, 组装三者

// import 

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
    final _loginViewModel = LoginViewModel();
  @override
  Widget build(BuildContext context) =>
  /// ChangeNotifierProvider
   ChangeNotifierProvider.value(
        value: _loginViewModel,
        child: MaterialApp(
        home: LoginWidget()
    );
  }
}

效果图

  • state == 0, 初始状态

state0.png
  • state == 1, 点击登录后,显示加载

state1.png
  • state == 2, 登录成功

state2.png

~λ:

  • 只是简单例子。mvvm作为思想,怎么抽离数据和ui视具体情况而定,灵活解决
  • 插件只是为了更好组织,而且差价来自flutter官方团队,并不是第三方野路子。善于利用工具
  • 也可尝试用原生 InheritedWidget 及其附属内容自己封装出provider的效果

相关文章

  • flutter mvvm 模式

    lzyprime 博客 2020.01.16 更新 yesterday, 收到网友反馈,照抄如下内容不好用,希望我...

  • Flutter 使用 Riverpod+Retrofit 构建M

    最近,在使用 Flutter 做一个图片分享的应用,自己创建出一套 Flutter 版的 MVVM 开发模式,觉得...

  • Flutter实现的一款精美仿开眼视频跨平台App

    Eyepetizer 一款基于Flutter实现的精美仿开眼视频跨平台App,采用MVVM模式进行开发,适合新手入...

  • 初识Vue

    1. MVVM模式 Vue采用MVVM(Model-View-ViewModel)模式实现,MVVM模式由MVC演...

  • Vue快速入门

    MVVM模式 什么是MVVM模式? MVVM(Model-View-ViewModel)是一种软件架构设计模式,由...

  • vue面试问题

    1.MVVM模式和MVC模式 MVVM模式是Model-View-ViewModel的缩写。MVVM是一种设计...

  • MVVM在前端(web)使用

    前端框架vue,MVVM模式 今天咱们不谈iOS,说说web(MVVM模式)。MVVM模式在前端开发应该还是挺多的...

  • MVVM模式架构设计

    环境 AndroidStudio 2.1 MVVM模式 MVVM模式:View,ViewModel,Model,三...

  • Vue之MVVM模式和第一个Vue程序

    一、MVVM模式和第一个Vue程序 目录:MVVM模式、第一个Vue程序 1.MVVM模式 1)什么是MVVM?M...

  • App开发技术栈

    跨平台 Flutter 编程语言 java kotlin 架构 mvvm jetpack

网友评论

    本文标题:flutter mvvm 模式

    本文链接:https://www.haomeiwen.com/subject/zjexictx.html