關於小程序的目錄結構,能夠說一開始你們都有各自的開發習慣和命名規則,但一旦項目變得複雜龐大的時候,你就發現管理起來和後期維護變得很麻煩,若是是 協同開發 的話,更容易出現 「互坑」 的狀況。javascript
智庫君在一年多的小程序開發中也跳過很多的坑,總結了一套還算好維護的目錄結構跟你們分享(僅供參考,以爲好拿去,以爲很差歡迎提出意見),如下是實戰項目中的結構示例:css
├─ 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的官方文檔,如今也添加了目錄結構說明:java
你們在開發過程當中確定會去看官方文檔,但不可能全看完纔開始寫代碼,大多數狀況都是用到了再看,本人也是,因此下面抽一些開發中遇到的重點來說:json
組件模板的寫法與頁面模板相同。組件模板與組件數據結合後生成的節點樹,將被插入到組件的引用位置上。 在組件模板中能夠提供一個 節點,用於承載組件引用時提供的子節點。canvas
<!-- 組件模板 -->
<view class="wrapper">
<view>這裏是組件的內部節點</view>
<slot></slot>
</view>
複製代碼
<!-- page頁/父頁面引用組件的頁面模板 -->
<view>
<component-tag-name>
<!-- 這部份內容將被放置在組件 <slot> 的位置上 -->
<view>這裏是插入到組件slot中的內容</view>
<view>在加載組件的頁面裏自定義內容,將沒有複用性的內容寫在這裏</view>
</component-tag-name>
</view>
複製代碼
頁面自定義部分默認是加載在組件上方。小程序
爲何要在引用組件的頁面添加這些內容呢?
由於組件其中一個重要的特色是複用性,可是有的時候可能要根據不一樣場景作一些自定義,若是在組件中寫大量的場景/邏輯判斷,會增長組件的冗餘,並且這些方法只是被複用一次的話,徹底能夠不寫到組件裏。bash
<!-- 外部引用組件的頁面傳入樣式 -->
<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個做用:app
//這裏只須要在後面 添加this對象
let ctx = wx.createCanvasContext('myCanvas', this);
複製代碼
其餘一些默認組件,遇到相似的問題,通常只要引用時傳入this對象便可解決。dom
在實際生產環境中,咱們經常須要控制各個組件之間的互相通訊/傳參,下面介紹下具體的用法:
設置監聽事件:
<!-- 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 的配置:
須要強調一點:建議你們不要在組件上bind太多的監聽,一方面之後管理起來會比較麻煩,另外一方面首次加載若是調用過多方法會引發數據渲染的卡頓。
Component官方文檔: developers.weixin.qq.com/miniprogram…
往期回顧:
[填坑手冊]小程序Canvas生成海報(一)
[拆彈時刻]小程序Canvas生成海報(二)