深入小程序系列之二Flutter 和小程序混编

Posted CNHK19

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入小程序系列之二Flutter 和小程序混编相关的知识,希望对你有一定的参考价值。

背景

本文我们将开一下脑洞,在 Flutter 工程基础上下集成及运行小程序方案。

先看一下效果如下:

 

 

 

新建 Flutter 样例工程

Flutter 的安装

Flutter 的安装可参考https://flutterchina.club/get-started/install/具体上主要执行以下三步即可。本文将使用 Flutter1.12.hotfix8 稳定版作为开发环境。

  1. 下载 FlutterSDK
  2. 配置 PATH 环境路径
  3. flutter doctor 检查环境

新建 Flutter 工程

flutter create --template=app --org=com.finogeeks.flutter --project-name=mini_flutter -i objc -a java ./mini_flutter

执行以上命令后,正常将会提示以下信息

All done!
[✓] Flutter: is fully installed. (Channel stable, v1.12.13+hotfix.8, on Mac OS X 10.15.3 19D76, locale zh-Hans-CN)
[✓] Android toolchain - develop for Android devices: is fully installed. (Android SDK version 29.0.3)
[✓] Xcode - develop for iOS and macOS: is fully installed. (Xcode 11.3.1)
[✓] Android Studio: is fully installed. (version 3.6)
[!] IntelliJ IDEA Ultimate Edition: is partially installed; more components are available. (version 2019.3.3)
[✓] VS Code: is fully installed. (version 1.42.1)
[!] Proxy Configuration: is partially installed; more components are available.
[✓] Connected device: is fully installed. (1 available)

Run "flutter doctor" for information about installing additional components.

In order to run your application, type:

  $ cd mini_flutter
  $ flutter run

Your application code is in mini_flutter/lib/main.dart.

注意!flutter 需要依赖本地安装对应的 iOS,Android 开发工具,即需要安装 Xcode 和 AndroidStudio。具体安装使用方法这里不赘述。 这里我们用 VSCode+Xcode 作为开发组合环境,如果要正常调试需要确保以下三个检查项目是正常的。

  1. [✓] Xcode - develop for iOS and macOS: is fully installed. (Xcode 11.3.1)
  2. Flutter: is fully installed. (Channel stable, v1.12.13+hotfix.8, on Mac OS X 10.15.3 19D76, locale zh-Hans-CN)
  3. VS Code: is fully installed. (version 1.42.1) [!] Proxy Configuration: is partially installed; more components are available.

集成小程序解析引擎

这里我们采用凡泰免费社区版的小程序解析引擎,只需要 10 行代码量不到即可完成小程序集成。

  1. 引入小程序引擎插件。在 pubspec.yaml 文件中引入小程序 Flutter 插件

yaml mop: ^0.2.0

  1. 在 main.dart 文件中增加以下小程序引擎初始化方法。 Mop.instance.initialize 这里需要用到 sdkkey 和 secret。可以直接在https://mp.finogeeks.com免费注册获取。注册使用方法可以参考接入指引

```dart

// Platform messages are asynchronous, so we initialize in an async method.
 Future<void> init() async 
   if (Platform.isIOS) 
     final res = await Mop.instance.initialize(
         \'22LyZEib0gLTQdU3MUauAYEY1h9s9YXzmGuSgQrin7UA\', \'9e05fa0015d7dbfa\',
         apiServer: \'https://mp.finogeeks.com\', apiPrefix: \'/api/v1/mop\');
     print(res);
    else if (Platform.isAndroid) 
     final res = await Mop.instance.initialize(
         \'22LyZEib0gLTQdU3MUauAYEY1h9s9YXzmGuSgQrin7UA\', \'9e05fa0015d7dbfa\',
         apiServer: \'https://mp.finogeeks.com\', apiPrefix: \'/api/v1/mop\');
     print(res);
   
   if (!mounted) return;
 

```

  1. 在主界面上增加三个按钮来打开小程序
Center(
    child: Container(
      padding: EdgeInsets.only(
        top: 20,
      ),
      child: Column(
        children: <Widget>[
          Container(
            width: 140,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(5)),
              gradient: LinearGradient(
                colors: const [Color(0xFF12767e), Color(0xFF0dabb8)],
                stops: const [0.0, 1.0],
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
              ),
            ),
            child: FlatButton(
              onPressed: () 
                Mop.instance.openApplet(\'5e3c147a188211000141e9b1\',
                    path: \'pages/index/index\', query: \'\');
              ,
              child: Text(
                \'打开画图小程序\',
                style: TextStyle(color: Colors.white),
              ),
            ),
          ),
          SizedBox(height: 30),
          Container(
            width: 140,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(5)),
              gradient: LinearGradient(
                colors: const [Color(0xFF12767e), Color(0xFF0dabb8)],
                stops: const [0.0, 1.0],
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
              ),
            ),
            child: FlatButton(
              onPressed: () 
                Mop.instance.openApplet(\'5e4d123647edd60001055df1\');
              ,
              child: Text(
                \'打开官方小程序\',
                style: TextStyle(color: Colors.white),
              ),
            ),
          ),
          SizedBox(height: 30),
          Container(
            width: 140,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(5)),
              gradient: LinearGradient(
                colors: const [Color(0xFF12767e), Color(0xFF0dabb8)],
                stops: const [0.0, 1.0],
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
              ),
            ),
            child: FlatButton(
              onPressed: () 
                Mop.instance.openApplet(\'5e637a18cbfae4000170fa7a\');
              ,
              child: Text(
                \'我的对账单\',
                style: TextStyle(color: Colors.white),
              ),
            ),
          ),
        ],
      ),
    ),
  )
  1. 运行 Flutter 程序
  2. 在代码根目录执行 flutter devices 查看本机安装的模拟器。
  3. 执行 flutter run --debug 运行示例,运行效果之如本文最前面所展示的图示。

本文示例代码: https://github.com/finogeeks/mop-flutter-demo

保姆级教程:写出自己的移动应用和小程序(篇八)

上一期我们学习了在小程序开发过程中,通过网络请求获取对应的服务器域名与请求接口的使用。本期文章中,我们重点学习如何在开发过程中使用小程序组件。

小程序的组件分为两类:

  1. 内置组件
  2. 自定义组件

为了方便讲解,本系列文章直接使用了微信小程序的要求进行讲解,但不要担心,在 FinClip 中,这一切内容都是通用的。


内置组件

内置组件指在小程序内部已经预先定义好的组件,开发者不需要特殊引用就可以在代码内直接使用,以下面代码为例:

<view>
<text>这是一个按钮</text>
<button bintap=foo>按钮</button>
</view>

<view>, <text>, <button> 均为内置组件。内置组件的更多使用方法可以参考​​微信小程序开发文档​​。

自定义组件

随着我们小程序开发的进行,编写的代码越来越多,页面级别的代码会越来越臃肿。这时,我们需要把代码拆分成更小粒度的单元,这样子可以让代码更易于维护,也更加容易复用。这个更小粒度的单元,也就是自定义组件。

有这么一个场景: 我们在一个页面当中,填写若干个手机号码,点击 “保存” 后把号码依次保存在 storage 的一个列表中,页面代码如下:

// wxml
<view>index 页面</view>
<view class="wrapper">
<input class="weui-input" bindinput="bindKeyInput" placeholder="请输入正确的手机号码" />
<button type=primary class="weui-btn" bindtap="updateTel" size="small">保存</button>
</view>
<view class="wrapper">
<input class="weui-input" bindinput="bindKeyInput" placeholder="请输入正确的手机号码" />
<button type=primary class="weui-btn" bindtap="updateTel" size="small">保存</button>
</view>
<view class="wrapper">
<input class="weui-input" bindinput="bindKeyInput" placeholder="请输入正确的手机号码" />
<button type=primary class="weui-btn" bindtap="updateTel" size="small">保存</button>
</view>

// js
Page(
data:
tel:
,
bindKeyInput(e)
this.setData(
tel: e.detail.value
)
,
getTelList()
return wx.getStorageSync(tel)
,
updateTel()
let telList = this.getTelList() || []
if(this.data.tel.length !== 11)
wx.showToast(
title: 请输入正确手机号码,
)
return

telList.push(this.data.tel)
wx.setStorage(
key: tel,
data: telList,
success(res)
wx.showToast(
title: 保存号码成功,
)
,
fail(res)


)

)
```

页面效果如下:

保姆级教程:写出自己的移动应用和小程序(篇八)_小程序

可以看到这里重复的模版代码非常多,看起来非常的臃肿。那么我们就可以把这些重复的代码抽取成一个自定义组件,然后在需要使用的地方重复调用就可以了。

比如我们可以这样操作:

第一步

我们在根目录新建一个 components 的文件夹, 然后选择新建 component

保姆级教程:写出自己的移动应用和小程序(篇八)_前端_02

第二步

命名一个 ‘saveTel’ 的文件,就会生成组件相关的文件及基础配置

保姆级教程:写出自己的移动应用和小程序(篇八)_小程序_03

第三步

我们把原本写在页面里面的代码迁移到组件中去

// 把这部分挪到 saveTel.wxml 中
<view class="wrapper">
<input class="weui-input" bindinput="bindKeyInput" placeholder="请输入正确的手机号码" />
<button type=primary class="weui-btn" bindtap="updateTel" size="small">保存</button>
</view>
// 把 index.js 挪到 saveTel.js 去,如下:
// 这里要注意几点:
// 1. 组件的 js 是由 Component 构造器包裹的
// 2. 组件的方法并不是像 Page 直接放在构造器配置对象中,而是放置在更深一层的 methods 中
Component(
/**
* 组件的属性列表
*/
properties:

,

/**
* 组件的初始数据
*/
data:
tel:
,

/**
* 组件的方法列表
*/
methods:
bindKeyInput(e)
this.setData(
tel: e.detail.value
)
,
getTelList()
return wx.getStorageSync(tel)
,
updateTel()
let telList = this.getTelList() || []
if(this.data.tel.length !== 11)
wx.showToast(
title: 请输入正确手机号码,
)
return

telList.push(this.data.tel)
wx.setStorage(
key: tel,
data: telList,
success(res)
wx.showToast(
title: 保存号码成功,
)
,
fail(res)


)


)
```

第四步

经过以上步骤,我们已经把整个 ‘输入并保存手机号’ 的逻辑/模版/样式从页面抽离出了组件,接下来,我们需要在页面中引入并使用这个组件,也就是“给页面添加已经处理好的组件”。

首先,我们需要知道我们要引用的组件在哪以及叫什么名字。这两个信息我们可以到页面对应的 . json 去配置。


"usingComponents":
"save-tel" : "/components/saveTel"


// save-tel 即我们给组件的命名,这里的命名可以自己随意发挥,但是建议要达意
// /components/saveTel 即我们引用组件的路径

配置完毕也代表着我们做好了组件的配置,接下来要去对应的页面模版引入组件:

// wxml
<view>index 页面</view>
<save-tel></save-tel>
<save-tel></save-tel>
<save-tel></save-tel>

效果如下,测试一下确保输入以及保存等功能应该都是正常的。

保姆级教程:写出自己的移动应用和小程序(篇八)_移动应用开发_04

至此,我们完成了从一个页面抽离公共逻辑到一个组件/组件的使用的操作。

总结

我们可以通过内置组件去实现我们小程序的基本功能,然后通过自定义组件去抽象公共模块增加小程序的复用性跟让其具有更加优雅的代码组织方式。

当然,自定义组件还有各个各样的高阶的功能,大家可以阅读​​微信小程序开发文档​​深入了解。

以上是关于深入小程序系列之二Flutter 和小程序混编的主要内容,如果未能解决你的问题,请参考以下文章

深入小程序系列 ReactNative和小程序混编

深入小程序系列之三 ReactNative和小程序混编

Flutter 提供者和小部件生命周期

有手就行系列:让每个人都能写出自己的移动应用和小程序

Flutter混编工程之通讯之路

Flutter混编工程之通讯之路