search
「大眾點評點餐」小程序開發經驗 02:視圖

「大眾點評點餐」小程序開發經驗 02:視圖

文 | 何延希何延希,美團點評工程師,4 年 web 開發經驗,現在是美團點評點餐團隊的一員。

上一期,知曉程序(微信號 zxcx0101)與大家分享了「大眾點評點餐」小程序團隊帶來的小程序技術分析。

本期,我們想要和大家分享下大眾點評點餐小程序中,有關 View 視圖層的一些開發經驗。

本文部分示例來自於「大眾點評點餐」小程序的菜單頁面。

頁面代碼結構為:

我們將要說的小程序的 View 視圖層,是由 WXML與 WXSS(

menu.less

)兩大部分組成,由組件——也就是視圖的最小單元——進行展示。

視圖層將邏輯層的數據(menu.json)反應為視圖,同時將視圖層中定義的事件發送給邏輯層。WXMLWXML(WeiXin Markup Language)與 HTML 對應,用於描述頁面的結構

,可以類比 React 的 JSX。項目中

m

使用 WXML 語法,一個頁面的頂層是

page

節點。在 WXML 中獲取邏輯層定義的數據后,我們通過一系列自己的語法和邏輯展示出這些數據。結構上,組件是視圖層的最小單元。我們可以通過以下方式,進行動態渲染。

1. 數據綁定數據綁定是最簡單的使用數據方式。

採用 Mustache 語法的變數替換,用雙大括弧將變數名包起來,包括組件的屬性也可以使用變數。

2. 邏輯運算雙大括弧中,可進行一些簡單運算操作

,包括四則運算、三目運算、邏輯判斷、字元串拼接等。

3. 條件渲染

與通常將渲染內容寫在

if

else

判斷條件中不同,

小程序的條件渲染,要求將條件直接寫在相應組件的如果渲染組件為多個,可將多個組件放在組件內,渲染條件置於<block>wx:if屬性中。

此時的組件,只充當容器作用,頁面中不會渲染。我們來看條件渲染實際應用的例子:

用上的實例:

4. 列表渲染

列表渲染,是將元素進行遍歷,並利用

wx:for

屬性值進行循環渲染。與此相關的還有以下幾個屬性:

  • wx:key:遍曆元素的唯一的標識符,主要用於數據動態變化時,DOM 的更新機制。數據不變,則可無視。

  • wx:for-item:遍曆元素的變數名,默認值為item

  • wx:for-index:遍曆元素下標的變數名,默認index

以上屬性的值都可以用字元串,但值中不要使用

-

等符號。例如

dish-item

,在使用時,小程序會將

{{dish-item}}-

解析成減號,造成取值失敗。在這裡,我們利用測試數據舉個例子:

以上代碼結構上分為兩層:

  • 第一層block循環遍歷testData數組,每個遍歷值變數名為mainitem

  • 第二層view循環遍歷mainitem數組,每個遍歷值變數名為subitem,展示第一層index、第二層idname屬性。

展示結果:

循環遍歷時,除官方說明的數組類型可以循環遍歷外,

對象類型也可通過wx:for進行屬性遍歷

。此時

for-index

為屬性的

key

值。例如,在上面例子中,將換成對象類型:

結果為:

5. 模板 & 引用

小程序中的模板,概念類似於 React 中的組件(components)。

我們可以在模板中定義代碼片段,然後在不同的地方進行調用

,減少重複的代碼量。如何定義一個模板呢?

我們使用name屬性,作為模板的名字,然後在<template/>內定義模板代碼片段就可以了

。定義后的使用方式有 2 種:

  • 使用include方式,將目標文件除了<template/>部分外的整個代碼引入。這樣的操作,相當於是將整個文件里的代碼拷貝到include位置,所以無法傳入參數。

  • 使用import方式,引入定義的文件,然後通過<template/>組件的is屬性,聲明需要的使用的模板,然後將模板所需要的data傳入。這樣的模板擁有自己的作用域,只能使用data傳入的數據。

需要注意的幾個地方:

  • 小程序只會import目標文件中定義的<template/>,不能引用目標文件中引用的<template/>

  • 小程序的模板中,只能單向使用傳入的數據,不像 React 可以利用 props 讓父子組件進行傳值。

我們以單個菜品組件為例,看看如何在小程序中使用模板:

6. 綁定事件事件名稱為字元串,會默認傳入event參數,無法定製其他參數。

我們一般將所需參數通過屬性,綁定至組件,再通過

e.currentTarget.dataset

獲取。例如這樣:

WXSS定義在app.less中的樣式為全局樣式

,可作用於每一個頁面。

在頁面里的樣式文件中定義的樣式為局部樣式

,只作用在對應的頁面,並會覆蓋

app.less中相同的選擇器。

例如,代碼結構中

menu.less

能且只能作用於。

WXSS 支持內聯樣式和選擇器兩種特性。style

可以接收動態的樣式,會在運行時會進行解析。但請盡量避免將靜態的樣式寫進

style

中,以免影響渲染速度。WXSS 支持選擇器。對於常用的選擇器,小程序目前支持以下這些:

目前不支持的選擇器有:

此外,還有幾個需要注意的地方:

  • 如之前提到,頁面的頂層是節點,所以想要修改作用於整個頁面的樣式、頂層節點樣式,請使用page選擇器。

  • 小程序目前不支持 Media Query。

2. 擴展的特性在 CSS 的基礎上,WXSS 還擴展了幾個特性。

首先是尺寸單位 RPX。這是小程序自創的單位,可以根據屏幕寬度進行自適應。RPX 將所有手機的屏幕寬度規定為 750 rpx。例如,在 屏幕寬度為 375 px 的 iPhone 6 上,換算出來 1 rpx = 0.5 px = 1 物理像素。我們建議設計師在開發微信小程序時,可以用 iPhone 6 作為視覺稿的標準。另外,由於數值較小時渲染時會存在四捨五入的情況,在較小屏幕上差距會很大,所以要求精確而較小的視圖內容需避免使用此單位。例如,下圖所示菜品的減號操作圖標的高度,iPhone 6 下是 2 px,iPhone 4s 下直接渲染成了1 px(實際比例值為 1.7 px)。而加號按鈕圖標高度,在 iPhone 6 下是 11 px,iPhone 4s 下,就渲染成了 9 px(實際比例值為 9.48 px)。這樣的差距,就會讓小程序在兩台手機上,看起來不那麼協調了。

關注微信號 zxcx0101,在後台回復「rpx」,一篇文章帶你看懂 RPX。

此外,

在小程序中使用語句,可以導入外聯樣式表

。具體的使用方式是:在

@import

后,寫上需要導入的外聯樣式表的相對路徑,用

;

符號表示語句結束。

組件

如前面 WXML 部分中所述,

組件是視圖層的基本組成單元

。它與 HTML 中的標籤類似,基於 Web Component 標準,屬性和內容的使用方法也和 HTML 標籤類似。組件名稱和屬性名稱,都必須使用小寫。

1. 組件列表2. 原生組件

如上統計,

均為系統原生組件。

原生組件相對來說性能和用戶交互方面會有所提升。以部分機型

input

元素

fixed

時喚起鍵盤被遮擋的問題舉例,在某魅族機型上 HTML 5 頁面中,父元素

fixed

的輸入框會被遮擋:

在同一機型中,小程序里的輸入框就不會被遮擋。

3. 組件屬性

小程序的組件中,支持以下的數據類型:

  • Boolean:布爾值

  • Number:數字

  • String:字元

  • Array:數組

  • Object:對象

  • EventHandler:事件處理函數名,事件綁定屬性(如bindtap

  • Any:任意屬性(不是很明白是什麼意思)

所有組件都有的共同屬性:

  • id:組件的唯一標識

  • class:組件的樣式類,和在 WXSS 中定義的類選擇器對應

  • style:內聯樣式

  • hidden:組件隱藏或顯示

  • data-*:自定義屬性,可傳入自定義數據。邏輯層事件處理函數中,可通過e.currentTarget.dataset獲取。

  • bindcatch:都是事件綁定,差別在於:bind不會阻止事件向上冒泡,catch可以阻止事件向上冒泡。

此外,各個組件都有自定義的特殊屬性,如

<icon>

組件的

size

屬性。你可以在官方文檔中查閱每個組件的不同屬性。

兼容性

根據官方文檔的說明:

  • 在 iOS 上,小程序的 JavaScript 代碼是運行在JavaScriptCore 中,是由 WKWebView 進行渲染,可用環境有 iOS 8、iOS 9、iOS 10。

  • 在 Android 上,小程序的 JavaScript 代碼通過 X5 JSCore 解析,由 X5 基於Mobile Chrome 37 內核進行渲染;

  • 在開發工具上,小程序的 JavaScript 代碼運行在 NW.js,由 Chrome WebView 進行渲染。

由於內核渲染表現不一致,在開發過程中,存在於 X5 瀏覽器和各類機型或系統的兼容性問題,一部分會在小程序中存在。

性能優化

前端常用的模板方案一般有 2 種:

  • 將模板編譯成 JS 函數代碼,通過字元串拼接的方式生成渲染的 DOM 節點。例如:Mustache / tpl(點評內部開發使用),數據更改時,會將 DOM 節點全部更新。

  • 字元串 parse 和 compile 后拼接渲染外,有自己的 DOM 節點更新機制。例如:Vue.js / React等,數據更改時通過 DOM Diff 演算法更新 DOM 節點。

當數據改變觸發渲染層重新渲染的時候,會校正帶有key的組件。

框架會確保他們被重新排序,而不是重新創建。這樣做,我們可以確保組件保持自身的狀態,並且提高列表渲染時的效率。小程序對組件的渲染方式我們不得而知,只能對開發中碰到的一些問題來推測。的解釋,可知

小程序的模板渲染屬於第二種,數據更新時會根據key進行渲染優化

。但小程序官方未提供相關介面或性能調試工具,所以項目中我們只能自己嘗試不同方案然後對比渲染速度。以菜單頁面為例,商戶菜品數量多者成百上千,優化后的效果對比還是比較明顯。由以上的描述,我們可以得出以下的優化建議:

  • 在菜單頁面,將菜品數據扁平化為一層,併合理利用key值。

  • 設計組件結構時採用精簡的組件結構,減少渲染時的數據遍歷和組件嵌套深度帶來的性能消耗。

  • 將數據變動的組件與數據不變的組件進行拆分,減少數據更改帶來的組件更新量,如將加減按鈕和菜品信息分離。

  • 使用動態載入等方式減小首屏渲染數據量,提升用戶體驗。

原文地址:本文由知曉程序授權轉載,關注微信號 zxcx0101,

在微信後台回復「

點餐

」,獲取「大眾點評點餐」小程序全套開發經驗。

▽ 點擊「閱讀原文」,發現更多優質小程序

熱門推薦

本文由 一點資訊 提供 原文連結

一點資訊
寫了5860316篇文章,獲得23312次喜歡
留言回覆
回覆
精彩推薦