摘要:官網的所有組件和模塊的截圖在官網擴展版塊,是可以找到封裝的方法步驟的。封裝組件的版塊,我把里面的組件代碼拿出來了,也是為了后面章節做鋪墊吧。
目錄
Weex系列(序) —— 總要知道原生的一點東東(iOS)
Weex系列(序) —— 總要知道原生的一點東東(Android)
Weex系列(1) —— Hello World項目
Weex系列(2) —— 頁面跳轉和通信
Weex系列(3) —— 單頁面還是多頁面
Weex系列(4) —— 老生常談的三端統一
Weex系列(5) —— 封裝原生組件和模塊
[Weex系列(6) —— css相關小結]
[Weex系列(7) —— web組件和webview]
[Weex系列(8) —— 是時候簡析一下流程原理了]
[Weex系列(9) —— 踩坑填坑的集錦]
[Weex系列(10) —— 先這么多吧想到再寫。。。]
哇,2019年了,時間總是那么快,快過新年了,忙點了也懶點了,還有點想家了,先祝大家新年快樂吧。
這一章官網上有介紹,但還是多帶帶拎出來講一講,因為后期這塊用的還是挺多的。
官網的所有組件和模塊的截圖:
在官網 擴展版塊,是可以找到封裝的方法步驟的。
自定義模塊iOS:
第一步:
新建 myModule.h
#import#import @interface myModule : NSObject @end
新建 myModule.m
#import "myModule.h" @implementation myModule WX_EXPORT_METHOD(@selector(log:)) - (void)log:(NSString *)inputParam { NSLog(@"%@",inputParam); } @end
第二步:
AppDelegate.m里面注冊module
[WXSDKEngine registerModule:@"myModule" withClass:[myModule class]];
Android:
第一步:
新建myModule.java
public class MyModule extends WXModule { //run JS thread @JSMethod (uiThread = false) public void log(String inputParam) { Log.d("自定義模塊:", inputParam); } }
第二步:
WXApplication.java里面注冊module
WXSDKEngine.registerModule("MyModule", MyModule.class);
最后:
在上層vue里面,我們可以require我們自己封裝的module,就能夠調用原生的log方法,分別在xcode和Android Studio的控制臺,看到hello weex的消息了。
這里需要強調一點的是:iOS和Android的module的名字方法要一致,這樣在vue里面才能統一的。
weex.requireModule("myModule").log("hello weex")自定義組件
組件封裝起來比模塊是麻煩許多的,一開始也是摸不著頭腦,后來就找到weexsdk里面封裝的組件,依樣畫葫蘆的開始了。
iOS:
第一步:
新建myComponent.h
#import "WXComponent.h" @interface myComponent : WXComponent- (void)notifyWebview:(NSDictionary *) data; - (void)reload; - (void)goBack; - (void)goForward; @end
新建myComponent.m
#import "myComponent.h" #import#import #import "WXUtility.h" #import "WXURLRewriteProtocol.h" #import "WXSDKEngine.h" #import @interface WXWebView : UIWebView @end @implementation WXWebView - (void)dealloc { if (self) { // self.delegate = nil; } } @end @interface myComponent () @property (nonatomic, strong) JSContext *jsContext; @property (nonatomic, strong) WXWebView *webview; @property (nonatomic, strong) NSString *url; @property (nonatomic, assign) BOOL startLoadEvent; @property (nonatomic, assign) BOOL finishLoadEvent; @property (nonatomic, assign) BOOL failLoadEvent; @property (nonatomic, assign) BOOL notifyEvent; @end @implementation myComponent WX_EXPORT_METHOD(@selector(goBack)) WX_EXPORT_METHOD(@selector(reload)) WX_EXPORT_METHOD(@selector(goForward)) - (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance { if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) { self.url = attributes[@"src"]; } return self; } - (UIView *)loadView { return [[WXWebView alloc] init]; } - (void)viewDidLoad { _webview = (WXWebView *)self.view; _webview.delegate = self; _webview.allowsInlineMediaPlayback = YES; _webview.scalesPageToFit = YES; [_webview setBackgroundColor:[UIColor clearColor]]; _webview.opaque = NO; _jsContext = [_webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; __weak typeof(self) weakSelf = self; _jsContext[@"$notifyWeex"] = ^(JSValue *data) { if (weakSelf.notifyEvent) { [weakSelf fireEvent:@"notify" params:[data toDictionary]]; } }; if (_url) { [self loadURL:_url]; } } - (void)updateAttributes:(NSDictionary *)attributes { if (attributes[@"src"]) { self.url = attributes[@"src"]; } } - (void)addEvent:(NSString *)eventName { if ([eventName isEqualToString:@"pagestart"]) { _startLoadEvent = YES; } else if ([eventName isEqualToString:@"pagefinish"]) { _finishLoadEvent = YES; } else if ([eventName isEqualToString:@"error"]) { _failLoadEvent = YES; } } - (void)setUrl:(NSString *)url { NSString* newURL = [url copy]; WX_REWRITE_URL(url, WXResourceTypeLink, self.weexInstance) if (!newURL) { return; } if (![newURL isEqualToString:_url]) { _url = newURL; if (_url) { [self loadURL:_url]; } } } - (void)loadURL:(NSString *)url { if (self.webview) { NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:url]]; [self.webview loadRequest:request]; } } - (void)reload { [self.webview reload]; } - (void)goBack { if ([self.webview canGoBack]) { [self.webview goBack]; } } - (void)goForward { if ([self.webview canGoForward]) { [self.webview goForward]; } } - (void)notifyWebview:(NSDictionary *) data { NSString *json = [WXUtility JSONString:data]; NSString *code = [NSString stringWithFormat:@"(function(){var evt=null;var data=%@;if(typeof CustomEvent==="function"){evt=new CustomEvent("notify",{detail:data})}else{evt=document.createEvent("CustomEvent");evt.initCustomEvent("notify",true,true,data)}document.dispatchEvent(evt)}())", json]; [_jsContext evaluateScript:code]; } #pragma mark Webview Delegate - (NSMutableDictionary *)baseInfo { NSMutableDictionary *info = [NSMutableDictionary new]; [info setObject:self.webview.request.URL.absoluteString ?: @"" forKey:@"url"]; [info setObject:[self.webview stringByEvaluatingJavaScriptFromString:@"document.title"] ?: @"" forKey:@"title"]; [info setObject:@(self.webview.canGoBack) forKey:@"canGoBack"]; [info setObject:@(self.webview.canGoForward) forKey:@"canGoForward"]; return info; } - (void)webViewDidStartLoad:(UIWebView *)webView { } - (void)webViewDidFinishLoad:(UIWebView *)webView { if (_finishLoadEvent) { NSDictionary *data = [self baseInfo]; [self fireEvent:@"pagefinish" params:data domChanges:@{@"attrs": @{@"src":self.webview.request.URL.absoluteString}}]; } } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { if (_failLoadEvent) { NSMutableDictionary *data = [self baseInfo]; [data setObject:[error localizedDescription] forKey:@"errorMsg"]; [data setObject:[NSString stringWithFormat:@"%ld", (long)error.code] forKey:@"errorCode"]; NSString * urlString = error.userInfo[NSURLErrorFailingURLStringErrorKey]; if (urlString) { // webview.request may not be the real error URL, must get from error.userInfo [data setObject:urlString forKey:@"url"]; if (![urlString hasPrefix:@"http"]) { return; } } [self fireEvent:@"error" params:data]; } } - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if (_startLoadEvent) { NSMutableDictionary *data = [NSMutableDictionary new]; [data setObject:request.URL.absoluteString ?:@"" forKey:@"url"]; [self fireEvent:@"pagestart" params:data]; } return YES; } @end
第二步:
AppDelegate.m里面注冊component
[WXSDKEngine registerComponent:@"myComponent" withClass:[myComponent class]];
這里需要說明:上面基本上是照著weexsdk里面的webview組件改的,而且就是改了一下名字,方法什么的大家就可以自由發揮了。
Android:
第一步:
新建myComponent.java
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.taobao.weex.ui.component; import android.content.Context; import android.net.Uri; import android.support.annotation.NonNull; import android.text.TextUtils; import android.view.View; import com.taobao.weex.WXSDKInstance; import com.taobao.weex.annotation.Component; import com.taobao.weex.adapter.URIAdapter; import com.taobao.weex.common.Constants; import com.taobao.weex.dom.WXDomObject; import com.taobao.weex.ui.view.IWebView; import com.taobao.weex.ui.view.WXWebView; import com.taobao.weex.utils.WXUtils; import java.util.HashMap; import java.util.Map; @Component(lazyload = false) public class myComponent extends WXComponent { public static final String GO_BACK = "goBack"; public static final String GO_FORWARD = "goForward"; public static final String RELOAD = "reload"; protected IWebView mWebView; @Deprecated public myComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, String instanceId, boolean isLazy) { this(instance,dom,parent,isLazy); } public myComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, boolean isLazy) { super(instance, dom, parent, isLazy); createWebView(); } protected void createWebView(){ mWebView = new WXWebView(getContext()); } @Override protected View initComponentHostView(@NonNull Context context) { mWebView.setOnErrorListener(new IWebView.OnErrorListener() { @Override public void onError(String type, Object message) { fireEvent(type, message); } }); mWebView.setOnPageListener(new IWebView.OnPageListener() { @Override public void onReceivedTitle(String title) { if (getDomObject().getEvents().contains(Constants.Event.RECEIVEDTITLE)) { Mapparams = new HashMap<>(); params.put("title", title); fireEvent(Constants.Event.RECEIVEDTITLE, params); } } @Override public void onPageStart(String url) { if ( getDomObject().getEvents().contains(Constants.Event.PAGESTART)) { Map params = new HashMap<>(); params.put("url", url); fireEvent(Constants.Event.PAGESTART, params); } } @Override public void onPageFinish(String url, boolean canGoBack, boolean canGoForward) { if ( getDomObject().getEvents().contains(Constants.Event.PAGEFINISH)) { Map params = new HashMap<>(); params.put("url", url); params.put("canGoBack", canGoBack); params.put("canGoForward", canGoForward); fireEvent(Constants.Event.PAGEFINISH, params); } } }); return mWebView.getView(); } @Override public void destroy() { super.destroy(); getWebView().destroy(); } @Override protected boolean setProperty(String key, Object param) { switch (key) { case Constants.Name.SHOW_LOADING: Boolean result = WXUtils.getBoolean(param,null); if (result != null) setShowLoading(result); return true; case Constants.Name.SRC: String src = WXUtils.getString(param,null); if (src != null) setUrl(src); return true; } return super.setProperty(key,param); } @WXComponentProp(name = Constants.Name.SHOW_LOADING) public void setShowLoading(boolean showLoading) { getWebView().setShowLoading(showLoading); } @WXComponentProp(name = Constants.Name.SRC) public void setUrl(String url) { if (TextUtils.isEmpty(url) || getHostView() == null) { return; } if (!TextUtils.isEmpty(url)) { loadUrl(getInstance().rewriteUri(Uri.parse(url), URIAdapter.WEB).toString()); } } public void setAction(String action) { if (!TextUtils.isEmpty(action)) { if (action.equals(GO_BACK)) { goBack(); } else if (action.equals(GO_FORWARD)) { goForward(); } else if (action.equals(RELOAD)) { reload(); } } } private void fireEvent(String type, Object message) { if (getDomObject().getEvents().contains(Constants.Event.ERROR)) { Map params = new HashMap<>(); params.put("type", type); params.put("errorMsg", message); fireEvent(Constants.Event.ERROR, params); } } private void loadUrl(String url) { getWebView().loadUrl(url); } private void reload() { getWebView().reload(); } private void goForward() { getWebView().goForward(); } private void goBack() { getWebView().goBack(); } private IWebView getWebView() { return mWebView; } }
第二步:
WXApplication.java里面注冊component
WXSDKEngine.registerComponent("myComponent", myComponent.class);
最后:
在上層vue里面,我們就可以直接使用封裝好的組件。
這里需要強調一點的是:iOS和Android的組件名字一定要一致,這樣在vue里面才能統一的。
小結
1、從上面可以看出不管是組件還是模塊,都是要iOS和Android各封裝一套的,而且名字還要一致,如果兼容web端,還要做web的擴展,這樣才能三端統一的。
2、封裝組件的版塊,我把weex sdk里面的web組件代碼拿出來了,也是為了后面webview章節做鋪墊吧。
3、建議大家可以多看看weex sdk的源碼,(這里請忘掉我只是一個前端,我干嘛還要學習oc、java的這些想法吧)其實也還好,也可能是目前我們的項目沒有太復雜,封裝的還不是很多,也還算簡單,谷歌上一搜基本都能解決吧。
最后祝大家新的一年,少點bug,多點money,越來越好吧。
如果喜歡就請點個贊收藏一下啦~~~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100842.html
摘要:官網的所有組件和模塊的截圖在官網擴展版塊,是可以找到封裝的方法步驟的。封裝組件的版塊,我把里面的組件代碼拿出來了,也是為了后面章節做鋪墊吧。 目錄 Weex系列(序) —— 總要知道原生的一點東東(iOS) Weex系列(序) —— 總要知道原生的一點東東(Android) Weex系列(1) —— Hello World項目 Weex系列(2) —— 頁面跳轉和通信 Weex系列(...
摘要:剛看到這仨頁面的時候,我就想著可以用路由,做成三端統一。樣式這部分真的三端基本是高度統一的,部分微調一下就可以了,也正是這樣,我們后續才能迅速解決和。終于不是談談三端統一了,也是真的體驗了一次,雖然最后有點出入,但是下次基本是沒問題了。 目錄 Weex系列(序) —— 總要知道原生的一點東東(iOS) Weex系列(序) —— 總要知道原生的一點東東(Android) Weex系列(...
摘要:由于最開始沒有一點點原生開發的經驗,所以我就直接用的腳手架初始化項目。那下面我們就從最最原始的項目開始吧,序篇太枯燥,自由發揮時間開始啦。執行如下代碼,最后會得到如圖的項目結構。入口文件等簡析進行了初始化。 目錄 Weex系列(序) —— 總要知道原生的一點東東(iOS) Weex系列(序) —— 總要知道原生的一點東東(Android) Weex系列(1) —— Hello Wor...
摘要:安卓要麻煩許多,網上大多也都是安卓的講解,我也是遇到了好多坑。我是在里面重新繪制了一下,在適配的時候會用到,安卓倒是沒有怎么處理。 目錄 Weex系列(序) —— 總要知道原生的一點東東(iOS) Weex系列(序) —— 總要知道原生的一點東東(Android) Weex系列(1) —— Hello World項目 Weex系列(2) —— 頁面跳轉和通信 Weex系列(3) ——...
閱讀 3652·2021-09-02 15:11
閱讀 4563·2021-08-16 10:47
閱讀 1560·2019-08-29 18:35
閱讀 3030·2019-08-28 17:54
閱讀 2843·2019-08-26 11:37
閱讀 1496·2019-08-23 16:51
閱讀 1798·2019-08-23 14:36
閱讀 1800·2019-08-23 14:21