国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

加推Weex實(shí)踐之路(上)

shuibo / 1890人閱讀

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

一、背景1.為什么是Weex

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

其一,接入Web頁面,一個(gè)頁面適配兩端;

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

對(duì)比內(nèi)容

React Native

Flutter

Weex

上手難度

一般

一般

容易

接入特點(diǎn)

適合開發(fā)整體App

適合開發(fā)整體App

適合單頁面

維護(hù)難度

一般

一般

容易

開發(fā)語言

React

Dart

Vue、Rax

框架體量

較重

較輕

Bundle大小

較大

不需要

較小

社區(qū)

豐富

新起之秀

不夠完善

支持終端

Android、iOS

Android、iOS、Web等

Android、iOS、Web

引擎

JSCore、V8

Flutter Engine

JSCore、V8

通過對(duì)比,最終選擇了Weex,有以下幾個(gè)主要原因:

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

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

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

2.Weex與Web

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

二、Weex基本原理

Weex支持 Vue 和 Rax兩個(gè)前端框架,由于前端團(tuán)隊(duì)使用Vue進(jìn)行日常開發(fā),為了降低上手成本,我們選擇Vue框架進(jìn)行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

負(fù)責(zé)

JSBundle

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

Render

線程進(jìn)行UI的更新。而

Render

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

Component

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

TextComponent。JSBridge

負(fù)責(zé)

JS

端與

Native

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

Module來完成

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

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

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

四、實(shí)踐與解決方案

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

    頁面間通信

    路由

Weex自身提供的navigator只支持簡單的在線資源,而不支持本地文件的加載,同時(shí)無法滿足動(dòng)態(tài)化的呈現(xiàn)方式和復(fù)雜參數(shù)傳遞,需要自行實(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: "這是下一個(gè)頁面所需的參數(shù)",
  },
})


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

    反向傳值

我們?cè)诳紤]反向傳值的問題時(shí),主要涉及兩種場(chǎng)景,一是Weex頁面反向傳值給Weex頁面,二是Native反向傳值給Weex頁面。我們可以使用Weex提供的基于W3C 規(guī)范的

BroadcastChannel

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

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

WXModuleKeepAliveCallback

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

我們有嘗試借鑒

BroadcastChannel

的實(shí)現(xiàn),通過Weex項(xiàng)目全局的JSContext對(duì)象來觸發(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,可以理解為一個(gè)頁面的實(shí)例對(duì)象,該流程需要在發(fā)送監(jiān)聽的頁面需要獲取上一個(gè)

Weex

頁面對(duì)應(yīng)的

weexInstance

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

----

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

needListen

來告知下一個(gè)頁面:

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

2. 頁面配置文件

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

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

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

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

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

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

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

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

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

1.部分屬性

屬性

類型

默認(rèn)值

描述

backgroundColor

HexColor

同項(xiàng)目配置

窗口背景色

navigationBarBackgroundColor

HexColor

同項(xiàng)目配置

導(dǎo)航欄背景色

navigationBarHidden

Bool

false

隱藏導(dǎo)航欄

navigationBarTitle

String

?

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

navigationBarTitleColor

HexColor

同項(xiàng)目配置

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

2.iOS特殊形式

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

present

Bool

false

Present頁面

presentWithNavigationBar

Bool

false

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

transition

Map

false

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

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

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

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進(jìn)制, 默認(rèn)為白色,可不傳




     "backgroundColor": "", // 16進(jìn)制, 默認(rèn)透明色,可不傳




     "borderColor": "", // 16進(jìn)制, 默認(rèn)無邊框,可不傳




     "borderWidth": 1, // 默認(rèn)無邊框,可不傳




     "cornerRadius": 1, // 默認(rèn)無圓角,可不傳




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

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

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

navigationBarTitleComponent

String

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

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

3. 陰影處理

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

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

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

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

Weex提供了

Stream

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

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

參數(shù)

類型

必填

描述

path

String

請(qǐng)求的路徑

method

String

請(qǐng)求的方式,默認(rèn)為’GET‘,支持’POST‘、’DELETE‘等

params

Map

請(qǐng)求所需的參數(shù)

timeout

Number

請(qǐng)求超時(shí)時(shí)間

customHost

String

自定義請(qǐng)求的Host

callback

Function

請(qǐng)求的回調(diào)

請(qǐng)求示例:

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


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


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

5. 圖片加載

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

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

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

綜上所述,我們?cè)O(shè)計(jì)了一種本地化方案,為每一個(gè)添加的圖片生成一個(gè)唯一性的ID,Native負(fù)責(zé)圖片的存儲(chǔ)、加載。

6. 刷新組件

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

1.屬性

屬性

類型

必填

描述

showRefresh

Bool

是否添加下拉刷新

showLoading

Bool

是否添加上拉刷新

refreshAtCreated

Bool

是否在初次顯示的時(shí)候,自動(dòng)進(jìn)行下拉刷新

2.事件

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

loading 事件:當(dāng) 被上拉時(shí)觸發(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ù)中手動(dòng)調(diào)用刷新的方法以觸發(fā)下拉刷新,然而在某些Android設(shè)備上面出現(xiàn)了白屏的情況。Weex對(duì)此做出了解釋:

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

7. 截屏

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

// 1. 標(biāo)簽生命ref
"poster">
// 2. 獲取到該element,實(shí)際上是一個(gè)Map const poster = this.$refs.poster // 3. 獲取Map中對(duì)應(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,進(jìn)行

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

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

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

1. Native定義PopView組件

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

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

3. 執(zhí)行動(dòng)畫

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

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

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

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

五、To Be Continued

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

熱更新

資源預(yù)加載

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

Weex資源打包自動(dòng)化,自動(dòng)加入終端倉庫

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

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


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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/6889.html

相關(guān)文章

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

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

    zhouzhou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<