深入折騰Weex,知乎日報客戶端開發
最後效果如下:
這個 demo 主要實踐 4 件事情:
1. 模組註冊
2. 元件註冊
2. Native 方法呼叫
4. Native 頁面切換 & 引數傳遞
整個 app 只有兩個頁面,都是純 Weex 編寫的,對於第一個頁面非常的簡單,佈局類似於 iOS 的 TableView
<template>
<scroller>
<container repeat="{{list}}" news_id="{{news_id}}" onclick="onclick">
<container class="cell">
<image class="thumb" src="{{src}}"></image>
<text class="title">{{title}}</text>
</container>
<text class="separator"></text>
</container>
</scroller>
</template>
然後我們使用 this.$sendHttp 發起 http 請求,這裡知道,Weex 僅僅是一個渲染引擎,對於 http 請求,mtop 請求,甚至圖片載入等功能,是需要業務注入實現類的。比如 WeexDemo 裡面的 sendHttp 就是注入了 WXStreamModule 模組,然後在實現裡面使用了 NSURLConnection,這個設計非常不錯,在具體的業務當中,你可以把實現程式碼替換成任何你想要的 HTTP 庫。
[WXSDKEngine registerModule:@"image" withClass:[WXImageModule class]];
[WXSDKEngine registerModule:@"stream" withClass:[WXStreamModule class]];
[WXSDKEngine registerModule:@"event" withClass:[WXEventModule class]];
這就是 Weex 註冊模組的原理,其中圖片模組是用 SDWebImage 實現的。我們同樣也可以將其他的 Native 方法註冊到模組裡面,例如:
WX_EXPORT_METHOD(@selector(log:));
- (void)log:(NSString *)text {
NSLog(@"LOG: %@", text);
}
然後在 JavaScript 程式碼裡面只需要用 this.$call(“event”, “log”, “Hello, World!”); 就能在 Native 裡面輸出 Hello World! 這提供了強大的擴充套件能力。
首頁的展示是較為簡單的,用的是 Weex 自帶的 Image 和 Text,但是詳情頁是一個 Web 頁面,貌似我還沒找到 Weex 提供的 WebView 渲染元件。(但是奇怪的是,我自建 WXWebViewComponent 的時候提示 Duplicated Symbol,難道是還未實現麼),所以我們需要自建一個 WXComponent,用於 WebView 渲染。
當然我們也可以使用 Native 程式碼開啟一個 WebView,不過這樣顯然不如純 Weex 實現有趣。
#import "WXHtmlNodeComponent.h"
#import <WebKit/WebKit.h>
@interface WXHtmlNodeComponent()
@property (nonatomic, strong) NSString *URL;
@property (nonatomic, strong) NSString *html;
@property (nonatomic, strong) WKWebView *webView;
@end
@implementation WXHtmlNodeComponent
WX_CUSTOM_ATTRIBUTE(url, URL, NSString)
WX_CUSTOM_ATTRIBUTE(html, html, NSString)
+ (Class)viewClass {
return [WKWebView class];
}
- (void)applyPropertiesToView:(UIView *)view {
[super applyPropertiesToView:view];
WKWebView *webView = (WKWebView *)view;
if (self.html.length > 0) {
[webView loadHTMLString:self.html baseURL:nil];
} else if (self.URL.length > 0) {
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.URL]]];
}
}
這個 Component 支援 url 和 html 兩種 attribute,意味著可以從 url 或者 html 程式碼渲染他。我們把它註冊到 webnode 這個名字上面,就能在詳情頁使用它了:
<template>
<container>
<WebNode url="{{context.url}}" class="webnode"></WebNode>
</container>
</template>
<script>
module.exports = {
data: {
context: "{{context}}"
}
}
</script>
<style>
.webnode {
height: 1222;
flex: 1;
}
</style>
然後最最關鍵的事情來了,當使用者點選一行的時候,我們要從首頁跳到詳情頁,而這兩個頁面都是 Weex 的(目前貌似 Weex 沒有提供這樣的能力)。
但是沒有關係,我們有 Module,這裡我實現了一套邏輯,包括了本地頁面 Push 和 Weex 頁面上下文傳遞邏輯。
- (void)push:(NSDictionary *)params {
ViewController *controller = [[ViewController alloc] init];
controller.URL = [NSURL URLWithString:params[@"url"]];
controller.context = params[@"context"];
UINavigationController *navigator = [(AppDelegate *)[[UIApplication sharedApplication] delegate] navigator];
[navigator pushViewController:controller animated:YES];
}
然後在首頁 onclick 的時候,只要把 context 帶到 Module 裡面的 push 方法,往下透傳過下一個 Weex 頁面,就能完成下個頁面的初始化。
onclick: function(e) {
var news_id = e.target.attr["news_id"];
var context = this;
var api = this.api(news_id);
this.get(api, function(json) {
var params = {
url: "next weex url",
context: {
url: json.share_url,
title: json.title
}
};
context.$call("event", "push", params);
});
}
具體來說,這裡面使用了一個資料繫結上面的技巧,我把 weex 頁面上的 data 欄位放置了一個 “{{context}}”
<script>
module.exports = {
data: {
context: "{{context}}"
}
}
</script>
這是一個佔位符,會在 Native Code 裡面被 Push 傳進來的 context 替換(這是一個 NSDictionary),處理的過程只是做一次字串替換
#import "WXHelper.h"
#import "JSONHelper.h"
@implementation WXHelper
+ (NSString *)scriptWithURL:(NSURL *)URL context:(NSDictionary *)context {
NSString *script = [[NSString alloc] initWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:nil];
if (context == nil || ![context isKindOfClass:[NSDictionary class]]) {
return script;
}
return [script stringByReplacingOccurrencesOfString:@""{{context}}""
withString:JSONStringWithObject(context) ?: @""];
}
@end
然後我們的上下文就會被繫結到下一個 weex 頁面,其實根據這個思路,我們可以做更多的 Weex 和本地的互動,甚至把它做成 Framework 方便使用。
整個流程如下:
首頁 weex 渲染 –> onclick –> module 傳遞上下文到下一個 weex –> weex 自定義元件 WebView 渲染
以上就是整個 demo 的完整思路。
最後
Weex 的模組註冊、元件註冊非常的有用,給業務擴充套件自己的能力,自定義自己的功能提供了強大的基礎。
當然也希望 Weex 可以在 Native 互動方面提供更多有用的方法。
相關文章
- [Android開發]知乎日報Android
- 折騰日記
- 開發JAXR客戶端客戶端
- 騰訊 客戶端開發 QT客戶端QT
- IE客戶客戶端程式開發的利器Bindows客戶端
- iOS客戶端開發與Web前端開發iOS客戶端Web前端
- 使用 .NET MAUI 開發 ChatGPT 客戶端UIChatGPT客戶端
- OPC客戶端開發過程整理客戶端
- 開發WebApp之PC客戶端WebAPP客戶端
- 客戶端GUI程式開發漫談客戶端GUI
- ntp協議及客戶端開發協議客戶端
- BCB 客戶端 tuxedo 開發例項客戶端UX
- Flutter混合開發玩Android客戶端FlutterAndroid客戶端
- 青芒 for Mac客戶端開發筆記Mac客戶端筆記
- BCB 客戶端 tuxedo 開發例項 (轉)客戶端UX
- vue 服務端渲染折騰記錄Vue服務端
- 客戶端釋出日誌測試客戶端
- 使用BindingX開發客戶端炫酷動畫客戶端動畫
- 用INDY9開發FTP客戶端_01FTP客戶端
- 富客戶端開發技術選型薦客戶端
- 網路開發基礎客戶端001客戶端
- 工程師日記-系統折騰篇工程師
- Java服務端和客戶端開發輔助工具UtilsJava服務端客戶端
- 深入剖析Redis客戶端Jedis的特性和原理Redis客戶端
- 仿知乎日報androidAndroid
- flutter開發的乾貨集中營客戶端Flutter客戶端
- Hyperledger fabric-SDK-GO客戶端開發篇(六)Go客戶端
- 頭條Android客戶端開發面經分享Android客戶端
- 純java開發的電子郵件客戶端Java客戶端
- 使用 Python 的 Tkinter模組 開發 IRC 客戶端Python客戶端
- Linux折騰Linux
- waydroid折騰
- huajiqaq/Hydrogen: 一個基於androlua+開發的第三方知乎安卓客戶端 (github.com)安卓客戶端Github
- ZooKeeper服務發現客戶端客戶端
- TCP程式設計之服務端和客戶端的開發TCP程式設計服務端客戶端
- 【2】Windows C++ Redis服務端搭建與客戶端開發WindowsC++Redis服務端客戶端
- 基於xmpp openfire smack開發之Android客戶端開發[3]MacAndroid客戶端
- zookeeper 開源客戶端ZkClient使用客戶端client