Weex是由阿里巴巴研發的一套移動跨平臺技術框架,研發的初衷是爲了解決移動開發過程當中頻繁發版和多端研發的問題。使用Weex提供的跨平臺技術,開發者能夠很方便的使用Web技術來構建高性能、可擴展的Native級別的性能體驗,並支持在Android、iOS、YunOS和Web等多平臺上進行部署。具體的說,當在項目中集成WeexSDK以後,就可使用JavaScript和現代流行的前端框架來開發移動應用。html
同時,Weex框架的結構是解耦的,渲染引擎與語法層是分開的,也不依賴任何特定的前端框架,目前主要支持Vue.js和Rax兩個前端框架。這樣一來,甚至可使用其餘前端框架來驅動Weex,打造三端一致的Native應用。前端
WeexBox是Weex的腳手架開發框架,和著名的WeexEros和WeexPlus的做用同樣。相比Weex,WeexBox具備以下的特色:vue
藉助weexbox提供的cli工具,咱們能夠快速的初始化工程項目。android
# 安裝 cnpm i -g @weexbox/cli # 新建一個weex工程 weexbox create projectName # 進入工程 cd projectName # 安裝依賴 cnpm i
初始化的項目裏已經內置了 @weexbox/debugger工具,它負責調試功能。ios
注意:確保電腦與手機處於同一網段。git
調試app時,須要在weex項目中運行以下命令:es6
npm run debug
此時會自動打開web,打開app的調試掃碼工具掃二維碼使pc與移動終端創建鏈接,當你看到相似如下這張圖,就表示鏈接成功了。
github
若是要單獨調試某個頁面,WeexBox也是支持的。web
npm run debug [vue/weex頁面的路徑]
打開app的調試掃碼工具,掃二維碼使pc與移動終端創建鏈接。
此時右上角有另一個二維碼,點開並掃描這個二維碼便可將這個JSbundle頁面載入真機渲染成原生頁面。
vue-router
同時,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。
修改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 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>
若是從bundle中加載圖片,src 以bundle://開頭,例如:
<image src="bundle://image.png"></image>
若是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>
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)