关于小程序的目录结构,能够说一开始你们都有各自的开发习惯和命名规则,但一旦项目变得复杂庞大的时候,你就发现管理起来和后期维护变得很麻烦,若是是 协同开发 的话,更容易出现 “互坑” 的状况。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生成海报(二)