Weex 使用总结

Weex 使用总结

什么是Weex ?

Weex 是一个使用 Web 开发体验来开发高性能原生应用的框架。
Weex 致力于使开发者能基于当代先进的 Web 开发技术,使用同一套代码来构建 Android、iOS 和 Web 应用。具体来讲,在集成了 WeexSDK 之后,你可以使用 JavaScript 和现代流行的前端框架来开发移动应用。

官网地址

github地址

阅读readme中使用说明

工作原理 查看

前端将代码生成一个weex的JS bundle,同时可以将此js bundle部署在云端供移动端加载。在移动端,会运行一个Javascript引擎来执行JS bundle,在iOS下是基于javascriptCore内核的iOS系统提供的JSContext。通过JScontext,实现界面渲染、数据存储、网络通信、调用设备功能及用户交互响应等功能。

在demo工程中,src是源码目录,dist是生成的weex目录,web是生成的在web端打开的目录。

c044d4eefb1fc79e8126234dc09692fb.png

集成Weex到已有应用

  1. 可使用pod引入,在应用启动时初始化,具体可参考 集成Weex到已有应用.

  2. Weex 支持整体页面渲染和部分渲染两种模式,你需要做的事情是用指定的 URL 渲染 Weex 的 view,然后添加到它的父容器上,父容器一般都是 viewController。

weex sdk提供了内置组件和模块

其中navigator提供了页面的前进与后退

扩展iOS功能

可通过添加自定义module、component和handler来扩展功能。

  1. module 是完成一个操作的方法集合,在 Weex 的页面中,允许开发者 require 引入。
    a8f13e5da1fb90ec000e44f68e4807c1.png

  2. handler hanlder是 WeexSDK engine 中一个 service 的概念,它可以被 component、module 和其他的 handler 实现中调用。

注册handler怎么实现的?

    [WXSDKEngine registerHandler:[OKBImageLoaderImpl new] withProtocol:@protocol(WXImgLoaderProtocol)];

+ (void)registerHandler:(id)handler withProtocol:(Protocol *)protocol{    
    [WXHandlerFactory registerHandler:handler withProtocol:protocol];
}

+ (void)registerHandler:(id)handler withProtocol:(Protocol *)protocol{        
    [[WXHandlerFactory sharedInstance].handlers setObject:handler forKey:NSStringFromProtocol(protocol)];
}

WXHandlerFactory 内部有一个字典类型的属性handlers,key为protocol name,value是一个handler实例。注册自定义的handler,会覆盖掉内置同协议的handler。

怎么使用handler?

获取handler的方式,例如获取navigationHandler,

id<WXNavigationProtocol> navigationHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXNavigationProtocol)];


+ (id)handlerForProtocol:(Protocol *)protocol
{    
    id handler = [[WXHandlerFactory sharedInstance].handlers objectForKey:NSStringFromProtocol(protocol)];
    return handler;
}


  1. component
    如果 Weex 内置的组件不能满足你的开发需求,可以自定义你自己的 component。例如内置的一些组件 div,image 和 text,JavaScript 可以直接对对应标签声明 ref 属性之后,直接可以调用对应方法的一个特性

添加页面周期事件

  1. 自定义一个ViewController取代weex提供的默认的VC WXBaseViewController,作为weex显示的VC。
  2. 在viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear中通过调用[[WXSDKManager bridgeMgr] fireEvent:_instance.instanceId ref:WX_SDK_ROOT_REF type:@"viewappear" params:nil domChanges:nil];发送事件。
  3. 因为WXNavigationDefaultImpl 中跳转VC使用的是WXBaseViewController,所以需要一个自定义的遵循WXNavigationProtocol协议的handler, 修改pushViewControllerWithParam和setNavigationBarHidden接口使用自定义的ViewController。 另外自定义的handler要在使用前注册。

weex打开h5

  1. 前端用a标签跳转到h5,会调用在上面自定义的navigationImpl的pushViewControllerWithParam:completion:withContainer,在里面通过参数param可取到要打开的url,param[@"url"] .
  2. 根据URL中query wh_weex判断是否打开weex界面.
    1. wh_weex=true push一个OKBWeexViewController VC。
    2. wh_weex=false push一个OKBWebViewController VC。

拦截所有URL

  1. 创建一个遵循WXURLRewriteProtocol协议的类OKBWeexURLRewriteImpl,重写- (NSURL *)rewriteURL:(NSString *)url withResourceType:(WXResourceType)resourceType withInstance:(WXSDKInstance *)instance ,在resourceType == WXResourceTypeLink 时 根据跳转规则决定下一步走weex还是webview.
  2. 在使用前注册此handler。
  3. 注意:这种方式会拦截所有URL,包括weex内打开weex页面、打开h5、weex页面内的数据请求。

添加UA

[WXAppConfiguration setExternalUserAgent:[@“UA”];

覆盖UA

  1. 根据现象看,覆盖UA将不能打开html格式的URL。
  2. 创建一个遵循WXResourceRequestHandler协议的类OKBWeexResourceRequestHandlerImpl,可参考WXResourceRequestHandlerDefaultImpl接口实现。在- (void)sendRequest:(WXResourceRequest *)request withDelegate:(id<WXResourceRequestDelegate>)delegate内,向request中添加UA。
  3. 在使用前注册此handler。

支持JS调规范

  1. 创建自定义module OKBWeexJSHandle,添加接口- (void)execute:(NSDictionary *)param callBack:(WXModuleCallback)callBack 根据 param 进行解析。
  2. 使用之前要注册module [WXSDKEngine registerModule:@"jsbridge" withClass:[OKBWeexJSHandle class]];
  3. JS端调用
openSafariButtonClick: function() {
    this.callNative({"uri":"window","method":"openBrowser","data":"https://www.baidu.com","success":"success","fail":""});
},
callNative: function (paramStr) {
      weex.requireModule("jsbridge").execute(paramStr, function(res) {
        weex.requireModule("jsbridge").debugLog(res);
      });
    }

调试

  1. 详细介绍请点这里
  2. 前提是安装node.js
  3. 全局安装weex-toolkit
    npm install weex-toolkit -g
  4. 用 weex create 命令来创建一个空的模板项目
    weex create awesome-app
  5. 命令执行完以后,在当前目录的 awesome-app 文件夹里就有了一个空的 Weex + Vue.js 项目。
  6. 下一步就是进入刚刚创建的文件夹,并且安装依赖,然后执行 npm start:
    cd awesome-app
    npm install
    npm start
    然后工具会启动一个本地的 web 服务,监听 8081 端口。你可以打开 http://localhost:8081 查看页面在 Web 下的渲染效果。 源代码在 src/ 目录中,你可以像一个普通的 Vue.js 项目一样来开发.
    awesome-app 下子目录 src 是源码,dist 是生成的weex文件,web中是网页端开发文件。可以编辑src下的index.vue来联调。

调试页面工具devtools

  1. Weex Devtools 能够方便调试 Weex 页面,但此功能离不开 Native 的支持。
  2. weex 详细介绍devtool

iOS内置module如下
+ (void)_registerDefaultModules
{
    [self registerModule:@"dom" withClass:NSClassFromString(@"WXDomModule")];
    [self registerModule:@"navigator" withClass:NSClassFromString(@"WXNavigatorModule")];
    [self registerModule:@"stream" withClass:NSClassFromString(@"WXStreamModule")];
    [self registerModule:@"animation" withClass:NSClassFromString(@"WXAnimationModule")];
    [self registerModule:@"modal" withClass:NSClassFromString(@"WXModalUIModule")];
    [self registerModule:@"webview" withClass:NSClassFromString(@"WXWebViewModule")];
    [self registerModule:@"instanceWrap" withClass:NSClassFromString(@"WXInstanceWrap")];
    [self registerModule:@"timer" withClass:NSClassFromString(@"WXTimerModule")];
    [self registerModule:@"storage" withClass:NSClassFromString(@"WXStorageModule")];
    [self registerModule:@"clipboard" withClass:NSClassFromString(@"WXClipboardModule")];
    [self registerModule:@"globalEvent" withClass:NSClassFromString(@"WXGlobalEventModule")];
    [self registerModule:@"canvas" withClass:NSClassFromString(@"WXCanvasModule")];
    [self registerModule:@"picker" withClass:NSClassFromString(@"WXPickerModule")];
    [self registerModule:@"meta" withClass:NSClassFromString(@"WXMetaModule")];
    [self registerModule:@"webSocket" withClass:NSClassFromString(@"WXWebSocketModule")];
    [self registerModule:@"voice-over" withClass:NSClassFromString(@"WXVoiceOverModule")];
}

iOS内置handler如下:
+ (void)_registerDefaultHandlers
{
    [self registerHandler:[WXResourceRequestHandlerDefaultImpl new] withProtocol:@protocol(WXResourceRequestHandler)];
    [self registerHandler:[WXNavigationDefaultImpl new] withProtocol:@protocol(WXNavigationProtocol)];
    [self registerHandler:[WXURLRewriteDefaultImpl new] withProtocol:@protocol(WXURLRewriteProtocol)];
    
}

iOS内置component如下:
+ (void)_registerDefaultComponents
{
    [self registerComponent:@"container" withClass:NSClassFromString(@"WXDivComponent") withProperties:nil];
    [self registerComponent:@"div" withClass:NSClassFromString(@"WXComponent") withProperties:nil];
    [self registerComponent:@"text" withClass:NSClassFromString(@"WXTextComponent") withProperties:nil];
    [self registerComponent:@"image" withClass:NSClassFromString(@"WXImageComponent") withProperties:nil];
    [self registerComponent:@"scroller" withClass:NSClassFromString(@"WXScrollerComponent") withProperties:nil];
    [self registerComponent:@"list" withClass:NSClassFromString(@"WXListComponent") withProperties:nil];
    [self registerComponent:@"recycler" withClass:NSClassFromString(@"WXRecyclerComponent") withProperties:nil];
    [self registerComponent:@"waterfall" withClass:NSClassFromString(@"WXRecyclerComponent") withProperties:nil];
    
    [self registerComponent:@"header" withClass:NSClassFromString(@"WXHeaderComponent")];
    [self registerComponent:@"cell" withClass:NSClassFromString(@"WXCellComponent")];
    [self registerComponent:@"embed" withClass:NSClassFromString(@"WXEmbedComponent")];
    [self registerComponent:@"a" withClass:NSClassFromString(@"WXAComponent")];
    
    [self registerComponent:@"select" withClass:NSClassFromString(@"WXSelectComponent")];
    [self registerComponent:@"switch" withClass:NSClassFromString(@"WXSwitchComponent")];
    [self registerComponent:@"input" withClass:NSClassFromString(@"WXTextInputComponent")];
    [self registerComponent:@"video" withClass:NSClassFromString(@"WXVideoComponent")];
    [self registerComponent:@"indicator" withClass:NSClassFromString(@"WXIndicatorComponent")];
    [self registerComponent:@"slider" withClass:NSClassFromString(@"WXSliderComponent")];
    [self registerComponent:@"cycleslider" withClass:NSClassFromString(@"WXCycleSliderComponent")];
    [self registerComponent:@"web" withClass:NSClassFromString(@"WXWebComponent")];
    [self registerComponent:@"loading" withClass:NSClassFromString(@"WXLoadingComponent")];
    [self registerComponent:@"loading-indicator" withClass:NSClassFromString(@"WXLoadingIndicator")];
    [self registerComponent:@"refresh" withClass:NSClassFromString(@"WXRefreshComponent")];
    [self registerComponent:@"textarea" withClass:NSClassFromString(@"WXTextAreaComponent")];
	[self registerComponent:@"canvas" withClass:NSClassFromString(@"WXCanvasComponent")];
    [self registerComponent:@"slider-neighbor" withClass:NSClassFromString(@"WXSliderNeighborComponent")];
    
    [self registerComponent:@"recycle-list" withClass:NSClassFromString(@"WXRecycleListComponent")];
    [self registerComponent:@"cell-slot" withClass:NSClassFromString(@"WXCellSlotComponent") withProperties: @{@"append":@"tree", @"isTemplate":@YES}];
    
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页