WeexBox 快速上手

概述

Weex是由阿里巴巴研发的一套移动跨平台技术框架,研发的初衷是为了解决移动开发过程中频繁发版和多端研发的问题。使用Weex提供的跨平台技术,开发者可以很方便的使用Web技术来构建高性能、可扩展的Native级别的性能体验,并支持在Android、iOS、YunOS和Web等多平台上进行部署。具体的说,当在项目中集成WeexSDK之后,就可以使用JavaScript和现代流行的前端框架来开发移动应用。

同时,Weex框架的结构是解耦的,渲染引擎与语法层是分开的,也不依赖任何特定的前端框架,目前主要支持Vue.js和Rax两个前端框架。这样一来,甚至可以使用其他前端框架来驱动Weex,打造三端一致的Native应用。

WeexBox是Weex的脚手架开发框架,和著名的WeexEros和WeexPlus的作用一样。相比Weex,WeexBox具有如下的特点:

  • 零配置,开箱即用的项目,自带最佳实践;
  • 无需安装 weex-toolkit;
  • 比 weex-debugger、weex-builder 更快的构建速度;
  • 支持 sass、es6、file-loader、uglify、eslint等;
  • 可通过审核的热更新,静默模式和强制模式随意切换;
  • N 多实用的 Module 扩展;

快速上手

支持的系统

  • Android 5.0 (API 21)+
  • iOS 10.0+

开发环境

  • Node:Nodejs 8.0+
  • AndroidStudio(仅限Android):AndroidStudio 3.0+
  • Xcode(仅限iOS):Xcode 10.0+
  • CocoaPods(仅限iOS):CocoaPods 1.5.0+

创建项目

借助weexbox提供的cli工具,我们可以快速的初始化工程项目。

# 安装
cnpm i -g @weexbox/cli

# 新建一个weex工程
weexbox create projectName

# 进入工程
cd projectName

# 安装依赖
cnpm i
复制代码

初始化的项目里已经内置了 @weexbox/debugger工具,它负责调试功能。

调试

注意:确保电脑与手机处于同一网段。

调试真机JSbundle

调试app时,需要在weex项目中运行如下命令:

npm run debug
复制代码

在这里插入图片描述
此时会自动打开web,打开app的调试扫码工具扫二维码使pc与移动终端建立连接,当你看到类似以下这张图,就表示连接成功了。
在这里插入图片描述

调试开发页面

如果要单独调试某个页面,WeexBox也是支持的。

npm run debug [vue/weex页面的路径]
复制代码

打开app的调试扫码工具,扫二维码使pc与移动终端建立连接。 此时右上角有另外一个二维码,点开并扫描这个二维码即可将这个JSbundle页面载入真机渲染成原生页面。

在这里插入图片描述

打包

同时,WeexBox初始化的项目里已经内置了 @weexbox/builder,它负责打包功能。

#编译开发环境
npm run develop

# 编译测试环境
npm run test

# 编译准生产环境
npm run preRelease

#编译生成环境
npm run release
复制代码

项目结构

.
├── config                  // 配置文件夹
│   ├── update-config.json  // 热更新的配置文件
│   └── weexbox-config.js   // 图片资源的配置文件
├── deploy                  // 输出文件夹
├── platforms               // 原生文件夹
│   ├── android             // Android工程
│   └── ios                 // iOS工程
├── src                     // vue源码文件夹
│   └── module              // 模块文件夹
│       └── page            // 页面文件夹
│           ├── App.vue     // vue源码
│           └── index.js    // 入口文件
└── static                  // 图片资源文件夹
复制代码

使用npm i命令安装依赖后,项目的结构如上。项目同时也搭建了app 的基础架构:在工程 platforms 文件夹中,会看到两个文件夹 android 、ios,Android 端使用 Android Studio 开发工具,导入 platforms/android 文件夹,构建打包生成项目的apk;iOS 端使用 Xcode 开发工具,导入 platforms/ios 文件夹,构建打包生成项目的ipa。

iOS集成WeexBox

集成SDK

修改Podfile文件,添加WeexBox依赖:

source 'https://github.com/cocoapods/specs.git'
platform :ios, '10.0'
inhibit_all_warnings!
use_modular_headers!

target 'WeexBoxExample' do
    pod 'WeexBox'
    
end
复制代码

初始化

在 AppDelegate.swift 中添加如下代码:

func application(_ application: UIApplication, 
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) 
    -> Bool {
        
    // 初始化 WeexBox
    WeexBoxEngine.setup()
        
    // 开启调试
    WeexBoxEngine.isDebug = true
        
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.backgroundColor = .white
        
    // 使用 WBNavigationController 作为导航基类
    window?.rootViewController = WBNavigationController(rootViewController: LaunchController())
        
    window?.makeKeyAndVisible()
        
    return true
}
复制代码

事件通知

WeexBox 提供了原生与weex互相通知的能力,可以用作原生之间的通知。主要借助Event来实现:

// 注册事件
Event.register()

// 发送事件
Event.emit()

// 注销事件
Event.unregister()

// 注销所有事件
Event.unregisterAll()
复制代码

网络

Network 类封装了Alamofire,原生和weex的网络请求都会走这里。

// 网络请求域名
Network.server = 你的网络请求域名

// 发起网络请求。如果url已经包含了域名,会忽略你上面的设置
Network.request(url)
复制代码

说明:原生也可以直接使用Alamofire,如果是这样,建议使用Network提供的sessionManager。大多数情况下app会有自己的网络封装,可以参考weexbox来实现自己的network module。

热更新

// 配置热更新地址
UpdateManager.serverUrl = hotdeployUrl

// 是否需要强制更新
UpdateManager.forceUpdate = true

// 执行热更新
UpdateManager.update { (state, progress, error, url) in
    switch state {
    case .Unzip:
        // 解压
    case .DownloadFile:
        // 下载
    case .UpdateSuccess:
        // 更新成功,可以进入APP
        // 如果开启了强制更新,会等到下载完成才会进入这里。否则就是静默更新,解压成功就会进入
    }
}
复制代码

路由

路由提供页面间的跳转功能。前端的路由可以参考:vue-router

注册路由

Router.register()
复制代码

说明:WeexBox 默认注册了weex和web,你可以在app初始化的时候重新注册,用你自己的VC覆盖它们。

路由实例的属性

// 页面名称
public var name: String = ""

// 下一个weex/web的路径
public var url: String?

// 页面出现方式:push, present
public var type: String = Router.typePush

// 是否隐藏导航栏
public var navBarHidden: Bool = false

// 需要传到下一个页面的数据
public var params: Dictionary<String, Any>?

// 打开页面的同时关闭页面
public var closeFrom: Int?

// 关闭页面的方向,默认和堆栈方向一致
public var closeFromBottomToTop = true

// 关闭页面的个数
public var closeCount: Int?
复制代码

打开页面

var router = Router()

// 原生页面
router.name = "你注册路由时的页面名称"

// weex页面
router.name = Router.nameWeex
router.url = "module/page.js"

// web页面
router.name = Router.nameWeb
router.url = "https://aygtech.github.io/weexbox"

router.open()
复制代码

关闭页面

var router = Router()
router.close()
复制代码

Android 集成 WeexBox

Android SDK使用Kotlin开发,并且100%兼容Java。 对于有追求的团队而言,强烈建议使用Kotlin来开发,开发速度和稳健度都会大幅提升!

初始化

在Android的 Application 中初始化WeexBox SDK。

override fun onCreate() {
    super.onCreate()

    // 初始化 WeexBox
    WeexBoxEngine.setup(this, null)

    // 开启调试
    WeexBoxEngine.isDebug = true
}
复制代码

事件通知

WeexBox 提供了原生与weex互相通知的能力,你可以将它用作原生之间的通知,不管是weex界面还是原生界面,只要注册了事件,都能接收到。

通过 Event 类,你可以在weex发送事件与注册事件:

// 注册事件
Event.register()

// 发送事件
Event.emit()

// 注销事件
Event.unregister()

// 注销所有事件
Event.unregisterAll()
复制代码

也可以 在原生代码中发送事件与注册事件。

// 注册事件
Event.register(this,"YourEventName") { //this为Activity或者Fragment
    //var value = it!!["key"]  it为发送事件传过来的Map<String,Any>,可不传
}

// 发送事件
Map<String, Object> map = new HashMap<>()
map.put("key", Object)
Event.emit("YourEventName", map)//map可为null

// 注销事件
Event.unregister(this, "YourEventName") //this为Activity或者Fragment

// 注销所有事件
Event.unregisterAll(this)
复制代码

网络

WeexBox的网络使用的是Retrofit的二次封装。原生和weex的网络请求都会走这里。

// 网络请求域名
Network.server = 你的网络请求域名

// 发起网络请求。如果url已经包含了域名,会忽略你上面的设置
Network.request(url)
复制代码

热更新

// 配置热更新地址
UpdateManager.serverUrl = hotdeployUrl

// 是否需要强制更新
UpdateManager.forceUpdate = true

// 执行热更新
UpdateManager.update { state, progress, error, url ->
    when (updateState) {
        UpdateManager.UpdateState.Unzip -> // 解压
        UpdateManager.UpdateState.DownloadFile -> // 下载
        UpdateManager.UpdateState.UpdateSuccess -> {
            // 更新成功,可以进入APP
            // 如果开启了强制更新,会等到下载完成才会进入这里。否则就是静默更新,解压成功就会进入
        ... // 还有各种状态码,参见下面表格,可以处理热更新各种情况,如热更新失败提示用户重启
        }
    }
}
复制代码

UpdateManager返回的状态有:

状态码 描述
Unzip 解压文件
UnzipError 解压文件出错
UnzipSuccess 解压文件成功
GetServer 获取服务器路径
GetServerError 获取服务器路径出错
DownloadConfig 下载配置文件
DownloadConfigError 下载配置文件出错
DownloadConfigSuccess 下载配置文件成功
DownloadMd5 下载md5文件
DownloadMd5Error 下载Md5出错
DownloadMd5Success 下载md5文件成功
DownloadFile 下载文件
DownloadFileError 下载文件出错
DownloadFileSuccess 下载文件成功
UpdateSuccess 更新成功

路由

注册路由

Router.register()
复制代码

说明:WeexBox 默认注册了weex和web,你可以在app初始化的时候重新注册,用你自己的VC覆盖它们。

路由实例的属性

// 页面名称
public var name: String = ""

// 下一个weex/web的路径
public var url: String?

// 页面出现方式:push, present
public var type: String = Router.typePush

// 是否隐藏导航栏
public var navBarHidden: Bool = false

// 需要传到下一个页面的数据
public var params: Dictionary<String, Any>?

// 打开页面的同时关闭页面
public var closeFrom: Int?

// 关闭页面的方向,默认和堆栈方向一致
public var closeFromBottomToTop = true

// 关闭页面的个数
public var closeCount: Int?
复制代码

打开页面

var router = Router()

// 原生页面
router.name = "你注册路由时的页面名称"

// weex页面
router.name = Router.nameWeex
router.url = "module/page.js"

// web页面
router.name = Router.nameWeb
router.url = "https://aygtech.github.io/weexbox"

router.open()
复制代码

关闭页面

var router = Router()
router.close()
复制代码

静态资源

图片加载

weexbox 支持 3 种图片加载方式:

网络加载

网络加载图片时,src 以http开头,例如:

<image src="https://aygtech.github.io/weexbox/logo.png"></image>
复制代码

从 APP bundle 中加载

如果从bundle中加载图片,src 以bundle://开头,例如:

<image src="bundle://image.png"></image>
复制代码

从 APP 文件中加载

如果src 不以上面两种方式开头,还可以从文件中加载,例如:

// iOS
<image src="file://var/mobile/Media/DCIM/100APPLE/IMG_0171.PNG"></image>
// Android
<image src="/storage/emulated/0/DCIM/Camera/IMG_20180917_145836.jpg"></image>

复制代码

modal

WeexBox内置了一些模块,但是这些模块相比其他的,如WeexEros和WeexPlus来说是明显偏少的。为此,你可以使用Weex提供的扩展机制来扩展自己的modal,相关内容可以参考:Weex快速上手

除了常见的:alert、confirm外,还延伸了一些更频繁使用的api,eg:actionSheet(操作表弹框)、showLoading(显示菊花)等,更加常态化、大众化以及多元化。

在这里插入图片描述

实现的示例代码如下:

# 引用
const modal = weex.requireModule('wb-modal')

# 警告弹框
modal.alert({
  title: '标题',
  message: '弹窗内容',
  okTitle: '确定'
}, (result) => {

})
// callback参数
result: {
  status: 0
}
复制代码

在这里插入图片描述

如果要打开外部的Module,需要使用wb-external。例如:

# 引用
const external = weex.requireModule('wb-external')

# 调用摄像头拍照,实现图片裁剪上传
external.openCamera({
  // 能否剪裁
  enableCrop: true,
  // 是否矩形剪裁,true为圆形剪裁
  isCircle: true,
  // 宽度
  width: 100,
  // 高度
  height:100
}, (result) => {

})

// callback参数
result: {
  status: 0,
  error: '',
  data: {
    // 图片的存储路径
    url: '/docment/123.png'
复制代码

更多的模块可以参考:传送门

目前,大前端开发的趋势越来越明显,与Weex同一技术系的RN早已声名远播,Weex作为后期之秀,目前还在不断的追赶和优化中虽然有各种bug被人诟病,但是,哪个优秀的技术发展没有经历这样的过程呢。“不经一番寒彻骨,怎得梅花扑鼻香”,相信通过大家的无私奉献,Weex社区也会变得越来越好。

本人正在完成《Weex跨平台开发实战》一书,有任何好的建议的可以留言,也欢迎大家踊跃提意见。(群:515980159)

猜你喜欢

转载自juejin.im/post/5c1c627ae51d45778a5c6eb7