跨平臺小程序開發風格指南

原文連接: https://github.com/ant-move/T...

這是 Antmove 團隊推出的小程序風格指南,該指南結合了微信小程序、支付寶小程序、百度小程序三大小程序框架特性沉澱而來的開發實踐指南,旨在於創建一份適用於各小程序平臺的開發規範,但願對衆多小程序開發者們有所幫助。css

下文中每一條規則的示例代碼以支付寶小程序語法爲例,其它小程序平臺等同。

規則歸類

先級 A:必要的

這些規則會幫你規避錯誤,因此學習並接受它們帶來的所有代價吧。這裏面可能存在例外,但應該很是少,且只有你同時精通 JavaScript 和 各小程序平臺開發規範才能夠這樣作。html

優先級 B:強烈推薦

這些規則可以在絕大多數工程中改善可讀性和開發體驗。即便你違反了,代碼仍是能照常運行,但例外應該儘量少且有合理的理由。vue

優先級 C:推薦

當存在多個一樣好的選項,選任意一個均可以確保一致性。在這些規則裏,咱們描述了每一個選項並建議一個默認的選擇。也就是說只要保持一致且理由充分,你能夠隨意在你的代碼庫中作出不一樣的選擇。請務必給出一個好的理由!經過接受社區的標準,你將會:git

  • 訓練你的思惟,以便更容易的處理社區共享的代碼;
  • 不作修改就能夠直接複製粘貼社區的代碼示例;
  • 可以常常招聘到和你編碼習慣相同的新人,至少跟小程序相關的東西是這樣的

優先級 D:謹慎使用

有些小程序的特性的存在是爲了照顧極端狀況或幫助老代碼的平穩遷移。當被過分使用時,這些特性會讓你的代碼難於維護甚至變成 bug 的來源。這些規則是爲了給有潛在風險的特性敲個警鐘,並說明它們何時不該該使用以及爲何。github

優先級 A 的規則:必要的 (規避錯誤)

組件名爲多個單詞,採用橫槓分割

這樣能夠避免和現有的以及將來的小程序基礎組件相沖突,由於基礎組件一版都是單個單詞的。json

支付寶小程序平臺組件命名不支持駝峯形式,橫槓形式的命名是都支持的。小程序

反例

"usingComponents": {
    "Todo": "../../dist/todo/index"
}

好例子

"usingComponents": {
    "todo-item": "../../dist/todo/index"
}

組件屬性

組件的 props 需定義類型和默認值。微信小程序

在支付寶小程序中,即便沒有在 props 中聲明的屬性,組件也是能夠接收到的,可是微信小程序和百度小程序是必須在組件中聲明的屬性才能接收到。微信

若是傳值類型不一樣組件也是接收不到的,因此請給一個明確的數據類型。框架

爲 for 設置鍵值

在組件上老是必須用 key 配合 v-for,以便維護內部組件及其子樹的狀態。

反例

<view>
  <view a:for="{{ todos }}">
    {{ todo.text }}
  </view>
</view>

好的例子

<view>
  <view a:for="{{ todos }}" a:key="item.id">
    {{ item.text }}
  </view>
</view>

避免 a:if 和 a:for 用在一塊兒

請不要把 a:if 和 a:for 同時用在同一個元素上。

通常咱們在兩種常見的狀況下會傾向於這樣作:

  • 爲了過濾一個列表中的項目 (好比 a:for="{{ users }}" a:if="item.isActive")。在這種情形下,請將 users 替換爲一個過濾後的數據字段 (好比 activeUsers),讓其返回過濾後的列表。
  • 爲了不渲染本應該被隱藏的列表 (好比 a:for="{{ users }}" a:if="{{ shouldShowUsers }}")。這種情形下,請將 a:if 移動至容器元素上。

反例

<view>
  <view
    a:for="{{ users }}"
    a:if="{{ item.isActive }}"
    a:key="{{ item.id }}"
  >
    {{ item.name }}
  </view>
</view>

好的例子

<view>
  <view
    a:for="{{ activeUsers }}"
    a:key="{{ item.id }}"
  >
    {{ item.name }}
  </view>
</view>

組件樣式設置做用域

對於應用來講,頂級 App 組件和佈局組件中的樣式能夠是全局的,可是其它全部組件都應該是有做用域的。

微信小程序默認是組件樣式隔離的,但咱們推薦經過 CSS Modules,那是一個基於 class 的相似 BEM 的策略,固然你也可使用其它的庫或約定。

這讓覆寫內部樣式更容易:使用了常人可理解的 class 名稱且沒有過高的選擇器優先級,並且不太會致使衝突。

支付寶小程序目前組件尚未做用域隔離功能,具筆者瞭解該功能即將發佈。

優先級 B 的規則:強烈推薦 (加強可讀性)

變量命名規避關鍵詞

變量的命名在 js 中是不能以關鍵詞及保留字命名的,會直接報錯,但在小程序中沒有這個嚴格的限制,但在這裏強烈建議不要以小程序的關鍵字命名。

小程序關鍵字示例:

  • App
  • Page
  • Component
  • props
  • properties
  • data
  • globalData
  • methods
  • getApp
  • onInit
  • didMount
  • didUpdate
  • created
  • detached
  • onShow
  • onHide

小程序並無嚴格的規定不能以上述等關鍵字命名,但編碼時應該避免,提高代碼的可讀性,當在組件中出現該類型的變量時,咱們能夠有一個直觀的理解。好比 this.data 就是獲取組件內部數據的,gloabel.Data 就是獲取應用數據的。

組件文件

請給每個組件一個單獨的目錄,而不是將多個組件混雜在一個目錄中。

反例

components/
|- Todo.js
|- Todo.acss
|- Todo.axml
|- Todo.json
|- TodoItem.js
|- TodoItem.acss
|- TodoItem.axml
|- TodoItem.json

好的例子

components/
|- Todo
  |- Todo.js
  |- Todo.acss
  |- Todo.axml
  |- Todo.json
|- TodoItem
  |- TodoItem.js
  |- TodoItem.acss
  |- TodoItem.axml
  |- TodoItem.json

組件文件命名

組件文件命名推薦一下兩種,請在項目中統一使用。

  • 駝峯命名,單詞大寫開頭 (PascalCase)
  • 橫槓命名,單詞小寫 (kebab-case)

混用文件命名方式有的時候會致使大小寫不敏感的文件系統的問題,因此更爲橫線鏈接命名。

反例

components/
|- mycomponent.axml
components/
|- myComponent.axml

好的例子

components/
|- Mycomponent.axml
components/
|- my-component.axml

基礎組件名

應用特定樣式和約定的基礎組件 (也就是展現類的、無邏輯的或無狀態的組件) 應該所有以一個特定的前綴開頭,好比 Base。

反例

components/
|- MyButton.axml
|- VueTable.axml
|- Icon.axml

好的例子

components/
|- BaseButton.axml
|- BaseTable.axml
|- BaseIcon.axml

單例組件名

只應該擁有單個活躍實例的組件應該以 The 前綴命名,以示其惟一性。

這不意味着組件只可用於一個單頁面,而是每一個頁面只使用一次。這些組件永遠不接受任何 prop,由於它們是爲你的應用定製的,而不是它們在你的應用中的上下文。若是你發現有必要添加 props,那就代表這其實是一個可複用的組件,只是目前在每一個頁面裏只使用一次。

反例

components/
|- Heading.axml
|- MySidebar.axml

好的例子

components/
|- TheHeading.axml
|- TheSidebar.axml

緊密耦合的組件名

和父組件緊密耦合的子組件應該以父組件名做爲前綴命名。

若是一個組件只在某個父組件的場景下有意義,這層關係應該體如今其名字上。由於編輯器一般會按字母順序組織文件,因此這樣作能夠把相關聯的文件排在一塊兒。

反例

components/
|- TodoList
  |- index.axml
|- TodoItem
  |- index.axml

好的例子

components/
|- TodoList
  |- index.axml
|- TodoListItem
  |- index.axml

組件名中的單詞順序

組件名應該以高級別的 (一般是通常化描述的) 單詞開頭,以描述性的修飾詞結尾。

反例

components/
|- ClearSearchButton.axml
|- RunSearchButton.axml

好的例子

components/
|- SearchButtonClear.axml
|- SearchButtonRun.axml

完整單詞的組件名

組件名應該傾向於完整單詞而不是縮寫。

編輯器中的自動補全已經讓書寫長命名的代價很是之低了,而其帶來的明確性倒是很是寶貴的。不經常使用的縮寫尤爲應該避免。

反例

components/
|- SdSettings.axml
|- UProfOpts.axml

好的例子

components/
|- StudentDashboardSettings.axml
|- UserProfileOptions.axml

多個屬性的元素

多個特性的元素應該分多行撰寫,每一個屬性一行。

在 JavaScript 中,用多行分隔對象的多個屬性是很常見的最佳實踐,由於這樣更易讀。

反例

<my-component foo="a" bar="b" baz="c"/>

好的例子

<my-component 
  foo="a" 
  bar="b" 
  baz="c"/>

模板中簡單的表達式

組件模板應該只包含簡單的表達式,複雜的表達式則應該重構爲計算屬性或方法。

複雜表達式會讓你的模板變得不那麼聲明式。咱們應該儘可能描述應該出現的是什麼,而非如何計算那個值。並且計算函數和方法使得代碼能夠重用。

反例

{{
  fullName.split(' ').map(function (word) {
    return word[0].toUpperCase() + word.slice(1)
  }).join(' ')
}}

好的例子

<!-- 在模板中 -->
{{ normalizedFullName }}
methods: {
  normalizedFullName: function () {
    let normalizedFullName =  this.fullName.split(' ').map(function (word) {
      return word[0].toUpperCase() + word.slice(1)
    }).join(' ')
    
    this.setData({
    normalizedFullName
    })
  }
}

屬性名做用域

小程序提供了組件間代碼公用的機制,微信和百度小程序提供 behavior 的功能,支付寶小程序提供 mixin 的功能,這裏建議給公用的代碼加上做用域區分。

反例

var myGreatMixin = {
  // ...
  methods: {
    update: function () {
      // ...
    }
  }
}

好的例子

var myGreatMixin = {
  // ...
  methods: {
    myGreatMixinUpdate: function () {
      // ...
    }
  }
}

優先級 C 的規則:推薦 (將選擇和認知成本最小化)

組件/實例的選項順序

組件/實例的選項應該有統一的順序.

這是咱們推薦的組件選項默認順序。它們被劃分爲幾大類,因此你也能知道從組件裏添加的新屬性應該放到哪裏。

  • 組合 (向選項裏合併屬性)

    • extends
    • mixins
  • 接口 (組件的接口)

    • externalClass
    • props/properties
  • 本地狀態

    • data
    • 組件私有數據
  • 事件 (經過響應式事件觸發的回調)

    • 生命週期鉤子

      • onInit
      • deriveDataFromProps
      • didMount
      • didUpdate
      • didUnmoun
  • 非響應式的屬性 (不依賴響應系統的實例屬性)

    • methods

優先級 D 的規則:謹慎使用 (有潛在危險的模式)

隱性的父子組件通訊

應該優先經過 prop 和事件進行父子組件之間的通訊,而不是 this.$parent 調用。

一個理想的小程序應用是 prop 向下傳遞,事件向上傳遞的。遵循這一約定會讓你的組件更易於理解。然而,在一些邊界狀況下經過獲取父子組件的實例來進行變動可以簡化兩個深度耦合的組件。

問題在於,這種作法在不少簡單的場景下可能會更方便。但請小心,不要爲了一時方便 (少寫代碼) 而犧牲數據流向的簡潔性 (易於理解)。

注: 微信小程序中可經過 relation 功能獲取父子組件,支付寶小程序可經過 ref 來獲取,請謹慎使用。

參考連接

  • version: 1.0.1
  • 更新時間:2019-09-09
相關文章
相關標籤/搜索