Weex 小白兒從0開(kāi)始, 改造原有網(wǎng)頁(yè)(舊版不支持Vue)

最新weex已經(jīng)改為支持Vue,舊的代碼.we代碼隨著更新迭代也會(huì)替換掉坎炼。項(xiàng)目還在繼續(xù)推進(jìn)weex的使用愧膀,隨后會(huì)更新最新一些自己使用weex-vue的總結(jié)。

以下為舊版weex開(kāi)發(fā)流程:


公司的app大量采用 hybrid 開(kāi)發(fā)谣光。iOS 在使用UIWebView時(shí)會(huì)消耗大量系統(tǒng)資源檩淋。 WKWebVIew 會(huì)是一個(gè)很好的解決方案。但是公司前端資源緊缺萄金,讓前端人員給iOS端做適配成本太高蟀悦。

iOS端首先試用Weex。如果可以的話捡絮,不止可以替換原有的web界面熬芜,復(fù)用網(wǎng)頁(yè)接口。還可以開(kāi)發(fā)一些強(qiáng)排版的native界面福稳,成熟之后涎拉,安卓直接使用。

參考文檔

開(kāi)發(fā)環(huán)境

  • macOS 10.12.1
  • atom (安裝 language-weex 高亮)
  • iTerm2
    • homebrew
    • brew install node //通過(guò)brew安裝node
    • npm install -g weex-toolkit *//通過(guò)node安裝 weex-toolkit *

初始化工程

  • 創(chuàng)建文件夾
    $ mkdir bookcover
  • 進(jìn)入 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 中的依賴(lài)
``` npm install ```
` node_modules/` 會(huì)創(chuàng)建很多依賴(lài)文件
如果提示 
`npm WARN babel-loader@6.2.5 requires a peer of babel-core@^6.0.0 but none was installed.
`
執(zhí)行以下命令
` npm install babel-core`

* 編譯項(xiàng)目
`npm run dev` 
* 啟動(dòng)輕量服務(wù)器 
`npm run serve` 

打開(kāi)瀏覽器的圆,輸入http://127.0.0.1:8080, 就會(huì)看到這個(gè)項(xiàng)目的效果.

以上步驟鼓拧,一個(gè)weex 的基本項(xiàng)目已經(jīng)創(chuàng)建好了≡铰瑁看詳細(xì)講解季俩,可以看上邊的兩個(gè)鏈接和weex源碼。


### 開(kāi)始創(chuàng)建自己的 .we 文件
源碼都在 `src` 目錄下梅掠,現(xiàn)在已經(jīng)包含一個(gè)`weex-bootstrap.we` 文件酌住。

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

打開(kāi)文件
`$ 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 是模板的意思,這樣創(chuàng)建.we 的模板阎抒,其他文件調(diào)用時(shí)酪我,使用文件名作為模板名字。 例如:`first.we`

// index.we
<template>
<div>
<first></first> // 模板名稱(chēng)
...
</div>
</template>

##### 樣式

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


##### 數(shù)據(jù)+交互 (ViewModel)

<script>
module.exports = {

** 數(shù)據(jù)部分 **
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)

##### 從子組件向父組件通信

// 子視圖代碼 發(fā)送事件

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

// 父視圖代碼 監(jiān)聽(tīng)
this.$on('notify', function(event) {
}

`notify`   為父視圖方法
`{a: 1}`   傳給父視圖的參數(shù)

##### 從父組件向子組件通信

// 父視圖vm獲取子視圖且叁,然后觸發(fā) changeImage
test: function (e) {
this.$vm('sub').$emit(
'changeImage',
'https://gtms02.alicdn.com/tps/i2/TB1QHKjMXXXXXadXVXX20ySQVXX-512-512.png' )
}

// 父視圖監(jiān)聽(tīng) changeImage 方法
created: function() {
this.$on('changeImage', function (e) {
this.imageUrl = e.detail }.bind(this))
}

##### 子組件通訊
weex官網(wǎng)沒(méi)有寫(xiě)都哭,個(gè)人通過(guò)以下方法解決: `子視圖1 ` -> `父視圖` -> `子視圖2`

#### We 生命周期
Weex 視圖模型現(xiàn)在支持生命周期內(nèi)的鉤子函數(shù),這些鉤子函數(shù)能被寫(xiě)為組件選項(xiàng):

* init: 在視圖模型的構(gòu)造函數(shù)開(kāi)始調(diào)用時(shí)激活逞带;
* created: 當(dāng)視圖模型監(jiān)聽(tīng)默認(rèn)數(shù)據(jù)欺矫,但還未編譯模板時(shí)激活;
* ready: 當(dāng)視圖模型監(jiān)聽(tīng)默認(rèn)數(shù)據(jù)并且編譯模板生成虛擬DOM后被激活展氓。

#### 找節(jié)點(diǎn)
* 父找子節(jié)點(diǎn)

// index.we
<template>
<div>
<first id = 'goto-top'></first> // 模板名稱(chēng)
...
</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` 導(dǎo)入 iOS工作區(qū)間。

### 實(shí)例
創(chuàng)建文件

├── 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;">點(diǎn)我試試</text>
<chapter id='lastChapter'></chapter>
<recommand></recommand>
</scroller>

</template>

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

> 因?yàn)閕ndex.we 為主視圖带饱,沒(méi)有具體視圖的實(shí)現(xiàn)毡代,所以此處沒(méi)有<style> 標(biāo)簽阅羹。

視圖分為是三部分 `header`, `chapter`, `remmend` 。根視圖為`scrollview`教寂。

三部分各自請(qǐng)求自己需要說(shuō)的數(shù)據(jù)捏鱼,然后刷新視圖。


### 擴(kuò)展
#### 網(wǎng)絡(luò)請(qǐng)求 (參考)

created: function() {
// 獲取url
var url = apis.getHeaderUrl();
// 獲取當(dāng)前視圖 酪耕,在回調(diào)中使用this取不到子視圖导梆。
var self = this;
// 發(fā)送請(qǐng)求
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 請(qǐng)求成功',
            'duration': 1
          })
        }else {
          modal.toast({
            'message': 'header 請(qǐng)求失敗',
            'duration': 1
          })
        }
      } catch(e) {
        modal.toast({
          'message': e,
          'duration': 1
        })
      }
    }, function(res){
    })
  },

### Weex 原理
分為**Server** 和 **客戶端** ,**服務(wù)器下發(fā)**


![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

#### 環(huán)境
* xcode 8.1
* cocoapods 1.1.1

####  步驟
* 創(chuàng)建支持pod項(xiàng)目 , `FirstWeex`
  編輯Podfile

pod SDWebImage
pod WeexSDK

* 創(chuàng)建圖片下載類(lèi)
`WXImgLoaderDefaultImpl:NSObject<WXImgLoaderProtocol, WXModuleProtocol>`

實(shí)現(xiàn) 看尼。iOS9之后記得配置info.plist 打開(kāi)http請(qǐng)求
  • (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)userInfo completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock
    {
    if ([url hasPrefix:@"http://"]) {
    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];
    }

}


此時(shí)會(huì)在 ViewController創(chuàng)建的時(shí)候,weex界面也會(huì)顯示盟步。
其實(shí)weex的本質(zhì)也是在UIView藏斩,所以像native的視圖是一樣進(jìn)行操作。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末却盘,一起剝皮案震驚了整個(gè)濱河市狰域,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黄橘,老刑警劉巖兆览,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異塞关,居然都是意外死亡抬探,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)帆赢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)小压,“玉大人,你說(shuō)我怎么就攤上這事椰于〕『剑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵廉羔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我僻造,道長(zhǎng)憋他,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任髓削,我火速辦了婚禮竹挡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘立膛。我一直安慰自己揪罕,他們只是感情好梯码,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著好啰,像睡著了一般轩娶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上框往,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天鳄抒,我揣著相機(jī)與錄音,去河邊找鬼椰弊。 笑死许溅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的秉版。 我是一名探鬼主播贤重,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼清焕!你這毒婦竟也來(lái)了并蝗?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤耐朴,失蹤者是張志新(化名)和其女友劉穎借卧,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體筛峭,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铐刘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了影晓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镰吵。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖挂签,靈堂內(nèi)的尸體忽然破棺而出疤祭,到底是詐尸還是另有隱情,我是刑警寧澤饵婆,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布勺馆,位于F島的核電站,受9級(jí)特大地震影響侨核,放射性物質(zhì)發(fā)生泄漏草穆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一搓译、第九天 我趴在偏房一處隱蔽的房頂上張望悲柱。 院中可真熱鬧,春花似錦些己、人聲如沸豌鸡。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)涯冠。三九已至炉奴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間功偿,已是汗流浹背盆佣。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留械荷,地道東北人共耍。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像吨瞎,于是被迫代替她去往敵國(guó)和親痹兜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理颤诀,服務(wù)發(fā)現(xiàn)字旭,斷路器,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • 因?yàn)榻细鞯卮笥暄陆校@幾天我也是在網(wǎng)上十分關(guān)注各地的水災(zāi)的新聞報(bào)道遗淳,好幾處的大堤決口,那翻滾的黃龍席卷了那么多的鄉(xiāng)村...
    櫻小落閱讀 392評(píng)論 0 0
  • 項(xiàng)目中使用了AES加密心傀,把手機(jī)號(hào)加密之后傳給了后臺(tái)屈暗,發(fā)現(xiàn)后臺(tái)(使用的PHP開(kāi)發(fā))只要遇到“+”的字符串就會(huì)變?yōu)榭崭?..
    博爾茨杰閱讀 2,902評(píng)論 4 1
  • 我們都想這只貓一樣,拼命地抓住救命稻草脂男,想要逃離這個(gè)黑洞养叛,尋找光明。
    小小京同學(xué)閱讀 245評(píng)論 4 4