Weex 小白儿从0开始, 改造原有网页(旧版不支持Vue)

最新weex已经改为支持Vue,旧的代码.we代码随着更新迭代也会替换掉。项目还在继续推进weex的使用,随后会更新最新一些自己使用weex-vue的总结。

以下为旧版weex开发流程:


公司的app大量采用 hybrid 开发。iOS 在使用UIWebView时会消耗大量系统资源。 WKWebVIew 会是一个很好的解决方案。但是公司前端资源紧缺,让前端人员给iOS端做适配成本太高。

iOS端首先试用Weex。如果可以的话,不止可以替换原有的web界面,复用网页接口。还可以开发一些强排版的native界面,成熟之后,安卓直接使用。

参考文档

开发环境

  • macOS 10.12.1
  • atom (安装 language-weex 高亮)
  • iTerm2
    • homebrew
    • brew install node //通过brew安装node
    • npm install -g weex-toolkit *//通过node安装 weex-toolkit *

初始化工程

  • 创建文件夹
    $ mkdir bookcover
  • 进入 bookcover ,初始化Weex工程
    weex init
    得到以下文件

prompt: Project Name: (detail) bookcover
file: .gitignore created.
file: README.md created.
file: index.html created.
file: package.json created.
file: src/weex-bootstrap.we created.
file: webpack.config.js created.

* 安装 package.json 中的依赖
``` npm install ```
` node_modules/` 会创建很多依赖文件
如果提示 
`npm WARN babel-loader@6.2.5 requires a peer of babel-core@^6.0.0 but none was installed.
`
执行以下命令
` npm install babel-core`

* 编译项目
`npm run dev` 
* 启动轻量服务器 
`npm run serve` 

打开浏览器,输入http://127.0.0.1:8080, 就会看到这个项目的效果.

以上步骤,一个weex 的基本项目已经创建好了。看详细讲解,可以看上边的两个链接和weex源码。


### 开始创建自己的 .we 文件
源码都在 `src` 目录下,现在已经包含一个`weex-bootstrap.we` 文件。

#### 查看源码 (三部分)

打开文件
`$ atom weex-bootstrap.we` 

#####  布局 (View)

<template>
<div class="ct" style="height: {{ctHeight}}">
<image class="img" style="width: 400px; height: 400px;" src="{{img}}"></image>
<text style="font-size: 42;">Hello Weex!</text>
</div>
</template>


> template 是模板的意思,这样创建.we 的模板,其他文件调用时,使用文件名作为模板名字。 例如:`first.we`

// index.we
<template>
<div>
<first></first> // 模板名称
...
</div>
</template>

##### 样式

<style>
.ct {
width: 750;
align-items: center;
justify-content: center;
}
.img {
margin-bottom: 20px;
}
</style>


##### 数据+交互 (ViewModel)

<script>
module.exports = {

** 数据部分 **
data: {
ctHeight: 800,
img: '//gw.alicdn.com/tps/i2/TB1DpsmMpXXXXabaXXX20ySQVXX-512-512.png_400x400.jpg'
},

** 逻辑 **
ready: function () {
this.ctHeight = this.$getConfig().env.deviceHeight
}
}
</script>


### 组件间通讯

[参考 Weex 组件通讯](http://alibaba.github.io/weex/cn/doc/syntax/comm.html)

##### 从子组件向父组件通信

// 子视图代码 发送事件

test: function () {
this._parent.$emit('notify', {a: 1})
}

// 父视图代码 监听
this.$on('notify', function(event) {
}

`notify`   为父视图方法
`{a: 1}`   传给父视图的参数

##### 从父组件向子组件通信

// 父视图vm获取子视图,然后触发 changeImage
test: function (e) {
this.$vm('sub').$emit(
'changeImage',
'https://gtms02.alicdn.com/tps/i2/TB1QHKjMXXXXXadXVXX20ySQVXX-512-512.png' )
}

// 父视图监听 changeImage 方法
created: function() {
this.$on('changeImage', function (e) {
this.imageUrl = e.detail }.bind(this))
}

##### 子组件通讯
weex官网没有写,个人通过以下方法解决: `子视图1 ` -> `父视图` -> `子视图2`

#### We 生命周期
Weex 视图模型现在支持生命周期内的钩子函数,这些钩子函数能被写为组件选项:

* init: 在视图模型的构造函数开始调用时激活;
* created: 当视图模型监听默认数据,但还未编译模板时激活;
* ready: 当视图模型监听默认数据并且编译模板生成虚拟DOM后被激活。

#### 找节点
* 父找子节点

// index.we
<template>
<div>
<first id = 'goto-top'></first> // 模板名称
...
</div>
</template>

``` var el = this.$el('goto-top')```

* 父找子上下文

this.$vm('goto-top').setTitle('Updated')

* 子找父
```this._parent```

### 将 .we 文件打包成 .js

$ weex index.we -o .

得到 `index.js` 文件。 
将`index.js` 导入 iOS工作区间。

### 实例
创建文件

├── module
│ ├── chapter.we
│ ├── header.we
│ ├── recommand.we
│ └── urls.js

├── src
│ ├── index.we

* `urls.js` 保存url地址
* `index.we` 为界面主入口
* 其他为子视图

index.we

<template>
<scroller>
<header id='header_id' style="margin-top: 128; " title="你好"></header>
<text onclick='updateTitle' style="padding: 40;">点我试试</text>
<chapter id='lastChapter'></chapter>
<recommand></recommand>
</scroller>

</template>

<script>
require('module/header.we');
require('module/chapter.we');
require('module/recommand.we');
...
</script>

> 因为index.we 为主视图,没有具体视图的实现,所以此处没有<style> 标签。

视图分为是三部分 `header`, `chapter`, `remmend` 。根视图为`scrollview`。

三部分各自请求自己需要说的数据,然后刷新视图。


### 扩展
#### 网络请求 (参考)

created: function() {
// 获取url
var url = apis.getHeaderUrl();
// 获取当前视图 ,在回调中使用this取不到子视图。
var self = this;
// 发送请求
stream.fetch({
method: 'POST',
url: url,
type: 'json',
body: 'bookId=0000&id=000&timestamp=1481188025939&sign=000000000000'
}, function(res) {
try {
var result = res.data.state;
if (result == 200) {
var body = res.data.data;

          self.initData(body);

          modal.toast({
            'message': 'header 请求成功',
            'duration': 1
          })
        }else {
          modal.toast({
            'message': 'header 请求失败',
            'duration': 1
          })
        }
      } catch(e) {
        modal.toast({
          'message': e,
          'duration': 1
        })
      }
    }, function(res){
    })
  },

### Weex 原理
分为**Server** 和 **客户端** ,**服务器下发**


![weex-jsRender.png](http://upload-images.jianshu.io/upload_images/695270-57154d329ac937f7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


**weex 翻译成native**

| weex| native|
|-------|-------|
| style, attribute |  WXDomObject |
| div, text,scoller, List... |  WXComponent |
| script|  WXModule |
| .we|  WXSDKInstance |



### iOS支持 Weex

#### 环境
* xcode 8.1
* cocoapods 1.1.1

####  步骤
* 创建支持pod项目 , `FirstWeex`
  编辑Podfile

pod SDWebImage
pod WeexSDK

* 创建图片下载类
`WXImgLoaderDefaultImpl:NSObject<WXImgLoaderProtocol, WXModuleProtocol>`

实现 。iOS9之后记得配置info.plist 打开http请求
  • (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)userInfo completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock
    {
    if ([url hasPrefix:@"//"]) {
    url = [@"http:" stringByAppendingString:url];
    }
    return (id<WXImageOperationProtocol>)[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:url] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {

    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
    if (completedBlock) {
    completedBlock(image, error, finished);
    }
    }];
    }

* AppDelegate配置weex
  • (void)initWeex {
    [WXAppConfiguration setAppGroup:@"Company"];
    [WXAppConfiguration setAppName:@"projectName"];
    [WXAppConfiguration setAppVersion:@"1.0"];

    [WXSDKEngine initSDKEnviroment];

    [WXLog setLogLevel:WXLogLevelError];

    // 图片下载
    [WXSDKEngine registerHandler:[WXImgLoaderDefaultImpl new] withProtocol:@protocol(WXImgLoaderProtocol)];
    }

*  加载 ViewController视图

  • (void)viewDidLoad {
    [super viewDidLoad];

    // 加载weex 视图
    [self render];
    }

  • (void)render {
    [_instance destroyInstance];

    _instance = [[WXSDKInstance alloc] init];
    _instance.viewController = self;
    _instance.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds));

    __weak typeof(self) weakSelf = self;
    _instance.onCreate = ^(UIView * view) {
    [weakSelf.view addSubview:view];
    };
    _instance.onFailed = ^(NSError *error) {
    NSLog(@"render onFailed");

    };
    _instance.renderFinish = ^(UIView *view) {
    NSLog(@"render finish");
    };

    NSURL * url = _url;
    if (!url) {
    url = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"js"];
    }

    if (url) {
    [_instance renderWithURL:url options:@{@"bundleUrl":url.relativeString} data:nil];
    }

}


此时会在 ViewController创建的时候,weex界面也会显示。
其实weex的本质也是在UIView,所以像native的视图是一样进行操作。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 因为江南各地大雨,这几天我也是在网上十分关注各地的水灾的新闻报道,好几处的大堤决口,那翻滚的黄龙席卷了那么多的乡村...
    樱小落阅读 370评论 0 0
  • 项目中使用了AES加密,把手机号加密之后传给了后台,发现后台(使用的PHP开发)只要遇到“+”的字符串就会变为空格...
    博尔茨杰阅读 2,745评论 4 1
  • 我们都想这只猫一样,拼命地抓住救命稻草,想要逃离这个黑洞,寻找光明。
    小小京同学阅读 233评论 4 4