深入折騰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 互動方面提供更多有用的方法。
相關文章
- 騰訊 客戶端開發 QT客戶端QT
- 使用 Flutter 開發知識小集 iOS/Android 客戶端FlutteriOSAndroid客戶端
- 開發JAXR客戶端客戶端
- 折騰日記
- huajiqaq/Hydrogen: 一個基於androlua+開發的第三方知乎安卓客戶端 (github.com)安卓客戶端Github
- 使用 .NET MAUI 開發 ChatGPT 客戶端UIChatGPT客戶端
- Flutter混合開發玩Android客戶端FlutterAndroid客戶端
- Vue知乎日報的學習筆記Vue筆記
- Flutter 版知乎日報簡單實現Flutter
- 【面經】七戰騰訊之移動客戶端開發實習生客戶端
- 青芒 for Mac客戶端開發筆記Mac客戶端筆記
- 網路開發基礎客戶端001客戶端
- 客戶給袁騰飛日當天發給使用者及
- flutter開發的乾貨集中營客戶端Flutter客戶端
- 使用BindingX開發客戶端炫酷動畫客戶端動畫
- 頭條Android客戶端開發面經分享Android客戶端
- 深入剖析Redis客戶端Jedis的特性和原理Redis客戶端
- 大知乎(基於ThinkPHP開發)PHP
- Java服務端和客戶端開發輔助工具UtilsJava服務端客戶端
- OPC客戶端開發工具WTopcclient補充說明客戶端client
- Hyperledger fabric-SDK-GO客戶端開發篇(六)Go客戶端
- TCP程式設計之服務端和客戶端的開發TCP程式設計服務端客戶端
- Kubernetes客戶端認證(三)—— Kubernetes使用CertificateSigningRequest方式簽發客戶端證書客戶端
- OAuth客戶端開源JDK:AppAuthOAuth客戶端JDKAPP
- 如何開啟客戶端加密特性客戶端加密
- 企業如何做好知乎口碑營銷?如何藉助知乎獲客?
- 埃森哲:端到端客戶服務報告
- dubbo客戶端客戶端
- Pulsar客戶端客戶端
- mqtt 客戶端MQQT客戶端
- 外貿客戶開發
- Flutter 開發一個 GitHub 客戶端 | 掘金技術徵文FlutterGithub客戶端
- 「完整案例」基於Socket開發TCP傳輸客戶端TCP客戶端
- 服務端,客戶端服務端客戶端
- 客戶端,服務端客戶端服務端
- Nacos - 客戶端心跳續約及客戶端總結客戶端
- 工程師日記-系統折騰篇工程師
- [北京海淀] 知乎招聘前端開發工程師,上知乎,做你最喜歡的開發!前端工程師
- windows tftp客戶端,5步掌握win7開啟tftp客戶端的方法教程WindowsFTP客戶端Win7