成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

加推Weex實踐之路(上)

shuibo / 1969人閱讀

摘要:我們參考小程序的設(shè)計思路進行了優(yōu)化升級,為每一個需要特有化配置的頁面添加一個格式的配置文件,配置文件包括導(dǎo)航欄的配置頁面級別的配置跳轉(zhuǎn)的配置等,將配置工程化標(biāo)準(zhǔn)化。設(shè)置導(dǎo)航欄按鈕包含按鈕樣式的數(shù)組通過完成按鈕事件的回調(diào)。

一、背景1.為什么是Weex

在公司快速發(fā)展的大環(huán)境下,App的更新迭代高速、高頻,技術(shù)團隊平均兩周便可誕生一款中型App,但App團隊只有6個人(iOS 、Android各3人),在確保效率、質(zhì)量的前提下,單純依靠Native的能力顯得步履蹣跚——我們亟需提升團隊效率,希望單人可完成原本2~3人的工作量。

其一,接入Web頁面,一個頁面適配兩端;

其二,選擇Weex、React Native、Flutter、Chameleon等跨平臺開發(fā)框架,主流框架對比如下:

對比內(nèi)容

React Native

Flutter

Weex

上手難度

一般

一般

容易

接入特點

適合開發(fā)整體App

適合開發(fā)整體App

適合單頁面

維護難度

一般

一般

容易

開發(fā)語言

React

Dart

Vue、Rax

框架體量

較重

較輕

Bundle大小

較大

不需要

較小

社區(qū)

豐富

新起之秀

不夠完善

支持終端

Android、iOS

Android、iOS、Web等

Android、iOS、Web

引擎

JSCore、V8

Flutter Engine

JSCore、V8

通過對比,最終選擇了Weex,有以下幾個主要原因:

    Weex的上手成本較低,且單頁面的支持更符合項目規(guī)劃;

    Vue框架,契合團隊的大前端環(huán)境;

    Weex承接了淘寶、飛豬等App的大量頁面,給予外界充足的信心。

2.Weex與Web

雖然Web頁面的上手、維護成本更低,但與Weex相比,同等頁面的Web包體積要比Weex大,Web頁面無法做到純Native的體驗,且頁面加載速度很難極致化,在某些設(shè)備上容易出現(xiàn)白屏。Weex所具備的下列優(yōu)勢,足以讓一個追求極致的團隊所青睞。

二、Weex基本原理

Weex支持 Vue 和 Rax兩個前端框架,由于前端團隊使用Vue進行日常開發(fā),為了降低上手成本,我們選擇Vue框架進行Weex開發(fā)。Weex的基本工作流程如下:

Weex we 文件 --------------前端(we源碼)

↓ (轉(zhuǎn)換) ------------------前端(構(gòu)建過程)

JS Bundle -----------------前端(JS Bundle代碼)

↓ (部署) ------------------服務(wù)器或本地

在服務(wù)器或本地上的JS bundle ----服務(wù)器或本地

↓ (編譯) ------------------ 客戶端(JS引擎)

虛擬 DOM 樹 --------------- 客戶端(Weex JS Framework)

↓ (渲染) ------------------ 客戶端(渲染引擎)

Native視圖 --------------- 客戶端(渲染引擎)

來自官網(wǎng)

除去前端頁面的編寫,Weex可劃分為

DOM

Render

、

JSBridge

三大塊(線程)。

DOM

負責(zé)

JSBundle

的解析、綁定、映射等處理,并通知

Render

線程進行UI的更新。而

Render

線程,即UI線程,負責(zé)

Component

的渲染,例如前端編寫的的標(biāo)簽,將被渲染成原生封裝的UI組件

TextComponent。JSBridge

負責(zé)

JS

端與

Native

端的雙向通信,通信的具體邏輯處理則由原生實現(xiàn)的一個個

Module來完成

。下圖是一個頁面被渲染的完整流程:

三、客戶端系統(tǒng)架構(gòu)

依托于Native,借助于前端,演變成大前端的架構(gòu),整體結(jié)構(gòu)如下圖。我們希望App作為終端,提供容器的能力,做好底層服務(wù),完美融合Weex、Web等跨平臺技術(shù)。

四、實踐與解決方案

以下記錄了實踐中遇到的一些較為重要、常見的問題,及其解決方案,它們貫穿了Weex頁面的生命周期。

    頁面間通信

    路由

Weex自身提供的navigator只支持簡單的在線資源,而不支持本地文件的加載,同時無法滿足動態(tài)化的呈現(xiàn)方式和復(fù)雜參數(shù)傳遞,需要自行實現(xiàn)一套完整的頁面跳轉(zhuǎn)規(guī)則。

在大量使用了

Web、Weex

技術(shù)的前提下,為了保證頁面跳轉(zhuǎn)、頁面間參數(shù)傳遞、回調(diào)等的統(tǒng)一便捷性,以及模塊間的解耦,跳轉(zhuǎn)目標(biāo)可配置化,采用了路由的形式來作為頁面間跳轉(zhuǎn)的技術(shù)方案。基本的路由形式以及完整的過程如下:

// 打開Web頁面
scheme:/web/open");

Weex中發(fā)起一次頁面跳轉(zhuǎn)的示例:

navigator.openUrl({
  url: "scheme://weex/open",
  params: {
    bundleUrl: "/dist/about.js",
    name: "這是下一個頁面所需的參數(shù)",
  },
})


// 備注: 而下一個頁面只需要在data中聲明一個與參數(shù)同名的屬性來接收具體的參數(shù)即可。

    反向傳值

我們在考慮反向傳值的問題時,主要涉及兩種場景,一是Weex頁面反向傳值給Weex頁面,二是Native反向傳值給Weex頁面。我們可以使用Weex提供的基于W3C 規(guī)范的

BroadcastChannel

來輕松滿足第一種場景。但是目前并沒有現(xiàn)成的API能滿足第二種場景,我們需要不斷的嘗試:

在頁面跳轉(zhuǎn)時將

WXModuleKeepAliveCallback

傳入下一個頁面,然后在合適的時候執(zhí)行該回調(diào)。這對于iOS客戶端很容易實現(xiàn),但由于Android在頁面間傳值時需要將參數(shù)序列化到內(nèi)存中,然后在對應(yīng)的頁面從內(nèi)存中反序列化出來,這會導(dǎo)致生成一個新的對象,從而無法完成回調(diào)。

我們有嘗試借鑒

BroadcastChannel

的實現(xiàn),通過Weex項目全局的JSContext對象來觸發(fā)廣播完成反向傳值,但最后無疾而終。

我們最后選擇使用

fireGlobalEvent

,步驟如下:

1.Weex添加事件監(jiān)聽
const globalEvent = weex.requireModule("globalEvent");
globalEvent.addEventListener("eventName", (e) => {
  // ...
});


2.原生頁面發(fā)送事件
weexInstance.fireGlobalEventCallback("eventName", params); // Android


[weexInstance fireGlobalEvent:seventName params:params]; // iOS

代碼中的weexInstance,可以理解為一個頁面的實例對象,該流程需要在發(fā)送監(jiān)聽的頁面需要獲取上一個

Weex

頁面對應(yīng)的

weexInstance

,可以以一種相對優(yōu)雅的方式告知下一級

----

在跳轉(zhuǎn)的路由中添加一個

needListen

來告知下一個頁面:

navigator.openUrl({
  url: "scheme://weex/open",
  params: {
    bundleUrl: "/dist/about.js",
    needListen: true,
  },
})

2. 頁面配置文件

起初Weex頁面導(dǎo)航欄、跳轉(zhuǎn)方式等配置,均在自建Module中進行處理,例如一個頁面要設(shè)置導(dǎo)航欄,我們需要在mounted方法中加入如下代碼:

created () {
    navigator.setTitle("導(dǎo)航欄標(biāo)題")
    navigator.setItems([{
      title: "按鈕",
    }])
}

這種不夠工程化、標(biāo)準(zhǔn)化的方式給后期的維護、跨項目移植、架構(gòu)升級造成了極大的干擾。

我們參考小程序的設(shè)計思路進行了優(yōu)化升級,為每一個需要特有化配置的Weex頁面添加一個json格式的配置文件,配置文件包括導(dǎo)航欄的配置、頁面級別的配置、跳轉(zhuǎn)的配置等,將配置工程化、標(biāo)準(zhǔn)化。

例如我為about頁面添加了配置文件,json文件的類容為:

{
    "navigationBarTitle": "導(dǎo)航欄標(biāo)題",
    "navigationItems": [{
        "title": "按鈕"
    }]
}

打包后的資源文件目錄如下,about.js、about.json文件在同級目錄:

那么一個完整的頁面打開步驟如下:

經(jīng)過擴展,配置文件變得更加豐富,先前麻煩的跳轉(zhuǎn)處理、彈框等都可以通過配置文件實現(xiàn),下面是一些常用的屬性介紹:

1.部分屬性

屬性

類型

默認值

描述

backgroundColor

HexColor

同項目配置

窗口背景色

navigationBarBackgroundColor

HexColor

同項目配置

導(dǎo)航欄背景色

navigationBarHidden

Bool

false

隱藏導(dǎo)航欄

navigationBarTitle

String

?

導(dǎo)航欄標(biāo)題

navigationBarTitleColor

HexColor

同項目配置

導(dǎo)航欄標(biāo)題顏色

2.iOS特殊形式

針對于iOS客戶端存在頁面需要Present等情況,可以設(shè)置以下屬性:

present

Bool

false

Present頁面

presentWithNavigationBar

Bool

false

Present頁面,并攜帶導(dǎo)航欄

transition

Map

false

以轉(zhuǎn)場的形式呈現(xiàn),并規(guī)定轉(zhuǎn)場的動畫表達式(默認背景alpha從0到1)

優(yōu)先級:transition > presentWithNavigationBar > present

transition中需定義動畫的表達式,Native則需要解析該表達式,并按照表達式執(zhí)行動畫。

3.設(shè)置導(dǎo)航欄按鈕

navigationItems

Array

[]

包含按鈕樣式的數(shù)組

通過fireEvent完成按鈕事件的回調(diào)。

按鈕樣式說明:

{
     "type": "TEXT", // "TEXT", "IMG", "TEXT_IMG",必傳




     "title": "標(biāo)題", // 文字標(biāo)題或者




     "image": "刷新", // 是圖片地址,圖片地址支持本地圖片和網(wǎng)絡(luò)圖片




     "textColor": "FFFFFF", // 16進制, 默認為白色,可不傳




     "backgroundColor": "", // 16進制, 默認透明色,可不傳




     "borderColor": "", // 16進制, 默認無邊框,可不傳




     "borderWidth": 1, // 默認無邊框,可不傳




     "cornerRadius": 1, // 默認無圓角,可不傳




     "font": 16, // 默認16號字體,可不傳
  
      "position": 0, // 默認0,可不傳, 0-左側(cè)顯示,1-右側(cè)顯示  
       
     "imagePosition": 0, // 0-圖片在左,文字在右,默認, 1- 圖片在右,文字在左,  2-圖片在上,文字在下,

4.自定義導(dǎo)航欄

例如滿足導(dǎo)航欄分段選擇的需求:

navigationBarTitleComponent

String

對應(yīng)的自定義Component的名稱

Component由原生自行實現(xiàn),并暴露API與Weex進行交互

3. 陰影處理

Weex對于iOS的支持比較友好,然而Android 端無法顯示陰影。 雖然文檔有明確指出此問題,但是Android sdk卻提供相關(guān)方法。也許是阿里的工程師嘗試解決,但效果并不理想。比較明顯的一點是,如果列表中的item使用陰影, 在列表滑動的時候會把陰影殘留在最初繪制的位置。Android的同學(xué)一直在嘗試解決此問題,最終也沒達到一個理想的效果。最后的降級方案是通過圖片來替代陰影,以下是Weex官方的注釋:

目前僅 iOS 支持 box-shadow 屬性,Android 暫不支持,可以使用圖片代替。

每個元素只支持設(shè)置一個陰影效果,不支持多個陰影同時作用于一個元素。

4. 網(wǎng)絡(luò)請求

Weex提供了

Stream

模塊來完成網(wǎng)絡(luò)請求,如果依賴于該模塊,請求頭、簽名等配置以及請求結(jié)果校驗都必須在Weex端完成,這對于一個全量Weex App而言無可厚非。但很多App的核心業(yè)務(wù)是使用Native完成,甚至?xí)短缀芏郬eb頁面,我們必須將所有的請求統(tǒng)一至Native,讓W(xué)eex更關(guān)心的是UI的呈現(xiàn)而非底層業(yè)務(wù)。

因此我們提供了自己的網(wǎng)絡(luò)請求模塊,Weex端調(diào)用Native提供的方法,并通過參數(shù)來決定請求,一些可選的參數(shù):

參數(shù)

類型

必填

描述

path

String

請求的路徑

method

String

請求的方式,默認為’GET‘,支持’POST‘、’DELETE‘等

params

Map

請求所需的參數(shù)

timeout

Number

請求超時時間

customHost

String

自定義請求的Host

callback

Function

請求的回調(diào)

請求示例:

// 1. 獲取原生Module
const nativeStream = weex.requireModule("nativeStream")


// 2. 設(shè)置基本參數(shù)
const options = {
  path:"/....",
  method: "POST",
  params: {
    id: "123"
  }
}


// 3. 發(fā)起請求
nativeStream.fetch(options, (res) => {
  if (res.code === 0) {
    succesCallback(res)
    return
  }
  failCallback(res)
}

5. 圖片加載

標(biāo)簽圖片的加載需要客戶端提供handler,目前支持遠程鏈接和打包生成的Bundle資源,并不直接支持相冊圖片以及拍照生成的圖片。其對Base64的支持,為我們顯示相冊圖片提供了一種思路。下圖表明了Weex頁面中選擇相冊圖片、拍照并進行顯示的流程:

通過上圖我們可以知道,一個簡單的圖片顯示流程,其實并不簡單,其中最為關(guān)鍵的是在進行第5步時所選擇方案。先上傳圖片對于程序員而言是最為便捷的方案,但是比較影響用戶體驗,圖片本應(yīng)該在需要上傳的時候進行上傳,而非因為技術(shù)隘口而干擾業(yè)務(wù)。

轉(zhuǎn)換為Base64可以提升用戶體驗,但是卻比較影響性能。在iOS端,將一張1M的圖片轉(zhuǎn)換為Base64所需要的時間≥45ms,第6、7步所消耗的時間則是30ms左右,這種時間消耗隨圖片大小以倍數(shù)增加。

綜上所述,我們設(shè)計了一種本地化方案,為每一個添加的圖片生成一個唯一性的ID,Native負責(zé)圖片的存儲、加載。

6. 刷新組件

由于Weex所提供的組件形式較單一,且存在交互Bug,我們自實現(xiàn)了一套刷新組件。通過屬性來確定刷新的顯示與否,并提供相應(yīng)的接口實現(xiàn)Weex與Native之間的交互。

1.屬性

屬性

類型

必填

描述

showRefresh

Bool

是否添加下拉刷新

showLoading

Bool

是否添加上拉刷新

refreshAtCreated

Bool

是否在初次顯示的時候,自動進行下拉刷新

2.事件

refresh 事件:當(dāng) 、 被下拉完成時觸發(fā),該事件由原生回調(diào)到Weex。

loading 事件:當(dāng) 、 被上拉時觸發(fā),該事件由原生回調(diào)到Weex。

"list"
      c
      :show-refresh="true"
      class="list"
      @refresh="refreshList"
      @loading="loadMoreList">
 

beginRefresh 事件:開始下拉刷新,由Weex調(diào)用。

beginLoading 事件:開始上拉刷新,由Weex調(diào)用。

endRefresh 事件:結(jié)束下拉刷新,由Weex調(diào)用。

endLoading 事件:結(jié)束上拉刷新,由Weex調(diào)用。

this.$refs.list.beginRefresh()
this.$refs.list.endRefresh()
3.refreshAtCreated屬性

如果不使用該屬性,則需要在created或者mounted函數(shù)中手動調(diào)用刷新的方法以觸發(fā)下拉刷新,然而在某些Android設(shè)備上面出現(xiàn)了白屏的情況。Weex對此做出了解釋:

和瀏覽器不同的是,Weex 的渲染流程是異步的,而且渲染出來的結(jié)果都是原生系統(tǒng)中的 View,這些數(shù)據(jù)都無法被 javascript 直接獲取到。因此在 Weex 上,Vue 的 mounted 生命周期在當(dāng)前組件的 virtual-dom (Vue 里的 VNode) 構(gòu)建完成后就會觸發(fā),此時相應(yīng)的原生視圖未必已經(jīng)渲染完成。

7. 截屏

Weex中完成截屏,只需要獲取到對應(yīng)的視圖層即可,Weex頁面在渲染時會為每一個組件生成一個唯一的ID,在JavaScript中更直觀的體現(xiàn)是ref,盡管Weex并不存在真正的DOM,但其依然支持ref的使用。具體的做法如下:

// 1. 標(biāo)簽生命ref
"poster">
// 2. 獲取到該element,實際上是一個Map const poster = this.$refs.poster // 3. 獲取Map中對應(yīng)的ref saveViewShot({ ref: poster.ref }) // 4. 獲取Component // iOS WXComponent *component = [weexInstance componentForRef:ref]; // Android WXComponent component = WXSDKManager.getInstance().getWXRenderManager().getWXComponent(mWXSDKInstance.getInstanceId(), ref); // 5. 獲取View,進行

8. 優(yōu)雅的彈窗

這是一個很簡單的彈框需求,視圖漸漸變大最后全屏展示。然而基于Weex現(xiàn)有的能力是無法實現(xiàn)的,第一點:Weex頁面默認的布局是從導(dǎo)航欄下面開始的,第二點:路由的跳轉(zhuǎn)方式并不能直接支持此種彈出方式,頁面默認是從右向左推出。

為了實現(xiàn)彈框的功能,我們需要四個步驟:

1. Native定義PopView組件

1. Weex搭建頁面,并以PopView為基礎(chǔ)進行布局

2. 全屏呈現(xiàn)頁面并隱藏導(dǎo)航欄

3. 執(zhí)行動畫

原生定義好PopView組件后,Weex頁面可以這樣布局:

結(jié)合第三點所提出的配置文件,我們將2、3步驟的控制放在配置文件當(dāng)中,最后寫出的配置文件為:

{
  navigationBarHidden: true, // 隱藏導(dǎo)航欄
  transition: {
    property:"scale", // popView的尺寸將由(0,0)變?yōu)轱@示大小
    duration: 2, // 動畫時間,單位(秒)
  },// 轉(zhuǎn)場顯示,并規(guī)定popView的顯示動畫
}

這只是最為簡單的例子,更復(fù)雜的動畫需要客戶端支持即可。

五、To Be Continued

以上概括了Weex接入的心路歷程,以及在實踐中遇到的基本問題,表明了Weex在團隊中的運用已經(jīng)暢通并日趨規(guī)范化,但是更深入的性能優(yōu)化、熱更新等需要我們繼續(xù)前行,以下是下一期文章將涉及的知識點:

熱更新

資源預(yù)加載

配置文件動態(tài)化

Weex資源打包自動化,自動加入終端倉庫

加推科學(xué)院公眾號

mp.weixin.qq.com/s/LxdQ6Eq2R…


文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/6889.html

相關(guān)文章

  • 踩坑--- 基于釘釘?shù)?em>Weex微應(yīng)用開發(fā)起手式(其實寫完發(fā)現(xiàn)變成Weex相關(guān)資料匯總了)

    摘要:問題,你可以在中文討論板塊提交問題,地址。文字展現(xiàn)必須使用標(biāo)簽關(guān)于端的點透事件需要在上層視圖上加上,如果上層視圖有事件,多加一個中間層,把加在空事件視圖上關(guān)于事件注意僅支持和,暫不支持。事件會在頁面就要關(guān)閉時被觸發(fā)。 好吧,我知道你來看這個文章,一定是遇到坑了,所以,把這幾個放在最開始吧 現(xiàn)在,如果你的團隊的技術(shù)棧是react,請嘗試這個吧,跟react很像,如果你的團隊一直使用rea...

    zhouzhou 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<