[填坑手冊]小程序目錄結構和component組件使用心得

小程序目錄結構

關於小程序的目錄結構,可以說一開始大家都有各自的開發習慣和命名規則,但一旦項目變得複雜龐大的時候,你就發現管理起來和後期維護變得很麻煩,如果是 協同開發 的話,更容易出現 “互坑” 的情況。

智庫君在一年多的小程序開發中也跳過不少的坑,總結了一套還算好維護的目錄結構跟大家分享(僅供參考,覺得好拿去,覺得不好歡迎提出意見),以下是實戰項目中的結構示例:

├─  app.js    --- 小程序加載時優先加載的入口JS
├─  app.json   ---入口文件和公共配置
├─  app.wxss     ---公共樣式表
├─  project.config.json     ---小程序全局配置文件
├─  sitemap.json     ---允許微信索引文件
│  
├─cloud-functions     ---雲函數
│  └─setCrypto      ---數據加密模塊,用戶加密一些數據
│          index.js
│          package.json
│          ...
│          ...
│          
├─components      ---小程序自定義組件
│  ├─plugins      --- (重點)可獨立運行的大型模塊,可以打包成plugins
│  │  ├─comment         ---評論模塊
│  │  │  │  index.js
│  │  │  │  index.json
│  │  │  │  index.wxml
│  │  │  │  index.wxss
│  │  │  │  services.js    ---(重點)用來處理和清洗數據的service.js,配套模板和插件
│  │  │  │      
│  │  │  └─submit    ---評論模塊子模塊:提交評論
│  │  │          index.js
│  │  │          index.json
│  │  │          index.wxml
│  │  │          index.wxss
│  │  │      
│  │  └─canvasPoster     ---canvas海報生成模塊
│  │          index.js
│  │          index.json
│  │          index.wxml
│  │          index.wxss
│  │          services.js    ---(重點)用來處理和清洗數據的service.js,配套模板和插件
│  │     ...
│  │     ...
│  │          
│  └─templates   ---(重點)模板,通過外部傳參的容器,不做過多的數據處理
│      │      
│      ├─slideshow     ---滾屏切換模板
│      │      index.js
│      │      index.json
│      │      index.wxml
│      │      index.wxss
│      │      service.js    ---(重點)用來處理和清洗數據的service.js,配套模板和插件
│      │      
│      └─works       ---作品模板
│          │  index.js
│          │  index.json
│          │  index.wxml
│          │  index.wxss
│          │  service.js
│          │  
│          ├─articlePlugin    ---作品模板中的文章類型
│          │      index.js
│          │      index.json
│          │      index.wxml
│          │      index.wxss
│          │      
│          ├─galleryPlugin    ---作品模板中的九宮格類型
│          │      index.js
│          │      index.json
│          │      index.wxml
│          │      index.wxss
│          │      
│          └─videoPlugin     ---作品模板中的視頻類型
│                  index.js
│                  index.json
│                  index.wxml
│                  index.wxss
│                  ...
│                  ...
│                  
├─config     ---自定義配置文件
│      config.js    ---存放基礎配置
│      constants.js   ---存儲常量
│      weui.wxss   ---第三方文件wxss,js等
│      ...
│      ...
│      
├─pages     ---小程序頁面
│  ├─user      ---用戶頁面
│  │      index.js
│  │      index.json
│  │      index.wxml
│  │      index.wxss
│  ├─news      ---新聞頁面
│  │      index.js
│  │      index.json
│  │      index.wxml
│  │      index.wxss
│  │      
│  └─home      ---首頁
│         index.js
│         index.json
│         index.wxml
│         index.wxss
│         ...   
│         ...   
│          
├─request      ---https請求管理(根據switch tab分類會比較好)
│      common.js    ---一些公共請求獲取,如兌換openId,unionId 等
│      news.js
│      uri.js     --- (重點)總的URI請求管理,方便切換和配置DEV,QA,PROD環境
│      user.js
│      ...
│      ...
│      
└─utils       ---功能組件
        logger.js    ---日誌管理
        util.js       ---公共小組件庫
        ...
        ...
        
例如微信自己的wepy的官方文檔,現在也添加了目錄結構說明:


爲什麼一定要寫這個目錄結構呢?
不知道大家有沒有發現,在以往的老項目交接和多人協同開發中,容易遇到別人寫的模塊,變量命名不準確,或者資料缺損,一次十來個方法/組件間的互相調用,直接把接(盤)手的人整懵逼了,所以智庫君覺得,無論是獨立開發,還是協同開發,留一份完整的目錄說明文檔是很有必要的,勿坑 他人 OR 未來的自己~~~

component使用心得

大家在開發過程中肯定會去看官方文檔,但不可能全看完纔開始寫代碼,大多數情況都是用到了再看,本人也是,所以下面抽一些開發中遇到的重點來講:

一、引用組件模板頁面的自定義

組件模板的寫法與頁面模板相同。組件模板與組件數據結合後生成的節點樹,將被插入到組件的引用位置上。
在組件模板中可以提供一個 <slot> 節點,用於承載組件引用時提供的子節點。

<!-- 組件模板 -->
<view class="wrapper">
  <view>這裏是組件的內部節點</view>
  <slot></slot>
</view>
<!-- page頁/父頁面引用組件的頁面模板 -->
<view>
  <component-tag-name>
    <!-- 這部分內容將被放置在組件 <slot> 的位置上 -->
    <view>這裏是插入到組件slot中的內容</view>
    <view>在加載組件的頁面裏自定義內容,將沒有複用性的內容寫在這裏</view>
  </component-tag-name>
</view>

頁面自定義部分默認是加載在組件上方

爲什麼要在引用組件的頁面添加這些內容呢?
因爲組件其中一個重要的特點是複用性,但是有的時候可能要根據不同場景做一些自定義,如果在組件中寫大量的場景/邏輯判斷,會增加組件的冗餘,而且這些方法只是被複用一次的話,完全可以不寫到組件裏。

二、“一鍵換膚”根據不同場景給組件引入外部樣式

<!-- 外部引用組件的頁面傳入樣式 -->
<WorkComponent extra-class="style1" j-data="{{workData}}"></WorkComponent>
//組件中js
Component({
    /**
    * 引入外部樣式,可傳多個class
    */
    externalClasses: ['extra-class','extra-class2'],
})

extra-class 從外部引入父級css,可用根據不同場景配置不同的樣式方案,這樣使得組件自定義能力更強。

三、數據清洗與容錯

//service.js  思路示例
module.exports = {
    /**
     * 功能:處理作者列表
     * @param list
     * @returns {Array}
     */
    authorList: function (list = []) {
        let result = [];
        list.forEach(item => {
            result.push({
                guid: item.recommend_obj_id || '',
                type: item.recommend_type || '',
                logo: (item.theme_pic || '').trim() || '',
                title: item.title || ''
            });
        });
        return result;
    }
};

如果外部傳入的數據要分別導入多個組件中,可以在組件中建立一個對應的service.js,有2個作用:

  1. 清洗數據,避免setData()的時有過多的髒數據
  2. 錯誤數據的兼容,添加數據缺省值,增加代碼健壯性

四、canvas在component組件中無法選中的問題

    //這裏只需要在後面 添加this對象
    let ctx = wx.createCanvasContext('myCanvas', this);

其他一些默認組件,遇到類似的問題,一般只要引用時傳入this對象即可解決。

五、組件之間的通訊

在實際生產環境中,我們常常需要控制各個組件之間的互相通信/傳參,下面介紹下具體的用法:

  • WXML 數據綁定:用於父組件向子組件的指定屬性設置數據,僅能設置 JSON 兼容數據(自基礎庫版本 2.0.9 開始,還可以在數據中包含函數)。具體在 組件模板和樣式 章節中介紹。
  • 事件:用於子組件向父組件傳遞數據,可以傳遞任意數據。
  • 如果以上兩種方式不足以滿足需要,父組件還可以通過 this.selectComponent 方法獲取子組件實例對象,這樣就可以直接訪問組件的任意數據和方法。

設置監聽事件:

<!-- wxml 中 當自定義組件觸發“myevent”事件時,調用“onMyEvent”方法 -->
<component-tag-name bindmyevent="setMyEvent" />
<!-- 或者可以寫成 -->
<component-tag-name bind:myevent="setMyEvent" />
// index.js 父頁面中
Page({
  setMyEvent: function(e){
    let self = this;
    if (e.detail) { // 自定義組件觸發事件時提供的detail對象
      switch (e.detail) {
        case "hidden":  //隱藏 懸浮框上的評論
          this.setData({
            isFixCommentShow: false
          });
          break;
        case "fixRefresh":   //刷新懸浮框
          this.setData({
            fixRefresh: true
          });
          break;
        case "commentRefresh":  //刷新評論
          this.setData({
            commentRefresh: Math.random()
          });
          break;
        case "createPoster":  //生成海報組件
          self.setPosterSave();
          break;
      }
    }
  }
})

父頁面引用子組件,子組件發送的信息,可以通過bind的方法監聽到,來獲取到具體的傳參值。

觸發事件

自定義組件觸發事件時,需要使用 triggerEvent方法,指定事件名、detail對象和事件選項:

<!-- 頁面 page.wxml -->
<another-component bindcustomevent="pageEventListener1">
   <my-component bindcustomevent="pageEventListener2"></my-component>
</another-component>
<!-- 組件 another-component.wxml -->
<view bindcustomevent="anotherEventListener">
   <slot />
</view>
<!-- 組件 my-component.wxml -->
<view bindcustomevent="myEventListener">
  <slot />
</view>
//組件中js
Component({
  properties: {},
  methods: {
    onTap: function(){
        var myEventDetail = {} // detail對象,提供給事件監聽函數
        var myEventOption = {} // 觸發事件的選項
        this.triggerEvent('myevent', myEventDetail, myEventOption)
        //myEventOption的一些配置:
        this.triggerEvent('customevent', {}, { bubbles: true }) // 會依次觸發 pageEventListener2 、 pageEventListener1
        this.triggerEvent('customevent', {}, { bubbles: true, composed: true }) // 會依次觸發 pageEventListener2 、 anotherEventListener 、 pageEventListener1
    }
  }
});

myEventOption 的配置:

  • bubbles(Boolean):事件是否冒泡
  • composed(Boolean):事件是否可以穿越組件邊界,爲false時,事件將只能在引用組件的節點樹上觸發,不進入其他任何組件內部
  • capturePhase(Boolean):事件是否擁有捕獲階段

需要強調一點:建議大家不要在組件上bind太多的監聽,一方面以後管理起來會比較麻煩,另一方面首次加載如果調用過多方法會引起數據渲染的卡頓。

Component官方文檔:
https://developers.weixin.qq....

往期回顧:

[[填坑手冊]小程序Canvas生成海報(一)](https://developers.weixin.qq....

[[拆彈時刻]小程序Canvas生成海報(二)](https://developers.weixin.qq....

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章