一、文档类型
.js : 逻辑控制,用于写javascript代码。
.wxml : 页面结构,用于写html。当然,微信对其有一定的封装,用的话还需要了解其标签。
.wxss : 样式表文件,用于写css。
.json : 样式配置,符合json语法格式。用来做其作用域内的设置。
小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。
1.1 以app命名的各个文件是整个app的全局配置文件,其必须放在项目的根目录下。
1.2 pages 目录下,为工程中的页面,每一个页面对应pages下的一个文件夹。文件夹名和文件名一致,不同文件以后缀区分(注意并不是每个文件都是必须的)。
注意:描述页面的这四个文件必须具有相同的路径与文件名。
2.组件
微信基于HTML封装了一系列的控件,旨在减少大家的开发难度与工作量
注意:所有组件与属性都是小写,以连字符 - 连接
二、注意点和快捷键
注意点
1. 微信小程序官方给出的定义是: 微信小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。其实他更像一个WEB APP,用户可以像打开一个网页一样打开一个微信小程序。所以,微信对小程序的要求是整体大小不能超过1MB。
2. .json 是配置文件,其内容必须符合JSON格式,所以文件内部不允许有注释。
3. app.json 是全局配置文件,微信小程序中的每一个页面的【路径+页面名】都需要写在 app.json 的 pages 中,且 pages 中的第一个页面是小程序的首页
4. .wxss 文件是样式表文件,app.wxss是全局的样式表文件。页面的样式表是非必要的。当有页面样式表时,页面的样式表中的样式规则会层叠覆盖 app.wxss 中的样式规则。如果不指定页面的样式表,也可以在页面的结构文件中直接使用 app.wxss 中指定的样式规则。 .json 文件具有相同的规则。
5. 每一个页面的路径名和文件名必须相同。
6. tabBar(客户端窗口的底部用于切换页面的tab栏)在 app.json 文件中配置,只能配置最少2个、最多5个 tab,显示顺序同tabBar标签下的pei
7. tabBar 的 iconPath 和 selectedIconPath 属性可以接受一个图片的路径,这个图片必须是本地图片不能是网络图片。
8. 像素单位最好使用 rpx ,微信会根据手机屏幕大小自适应。
9. 微信小程序存放资源文件,需要在根目录下创建文件夹,引用时以 /文件夹名/资源名 的形式引用。
10. 一个应用同时只能打开5个页面。wx.navigateTo 打开页面不会销毁之前的页面,如果页面层数较多注意使用 wx.redirectTo。
快捷键
格式调整
- Ctrl+S:保存文件
- Ctrl+[, Ctrl+]:代码行缩进
- Ctrl+Shift+[, Ctrl+Shift+]:折叠打开代码块
- Ctrl+C Ctrl+V:复制粘贴,如果没有选中任何文字则复制粘贴一行
- Shift+Alt+F:代码格式化
- Alt+Up,Alt+Down:上下移动一行
- Shift+Alt+Up,Shift+Alt+Down:向上向下复制一行
- Ctrl+Shift+Enter:在当前行上方插入一行
光标相关
- Ctrl+End:移动到文件结尾
- Ctrl+Home:移动到文件开头
- Ctrl+i:选中当前行
- Shift+End:选择从光标到行尾
- Shift+Home:选择从行首到光标处
- Ctrl+Shift+L:选中所有匹配
- Ctrl+D:选中匹配
- Ctrl+U:光标回退
界面相关
- Ctrl + \:隐藏侧边栏
- Ctrl + m: 打开或者隐藏模拟器
三、网络请求
在小程序中网络请求大致分为四种类型。
· 普通HTTPS请求(wx.request)
· 上传文件(wx.uploadFile)
· 下载文件(wx.downloadFile)
· WebSocket通信(wx.connectSocket)
这里主要讲 wx.request:
使用wx.request可以发起一个http请求,一个微信小程序被限制为同时只有5个网络请求。注意是同时。
wx.request({
url: 'http://192.168.1.137:80/app/guanggao',
method: 'POST',
data: {
type: "1"
},
header: {
'Accept': 'application/json'
},
success: function (res) {
that.setData({
images: res.data.data.guanggao
})
}
fail:function(err){
console.log(err)
}
})
上面的代码会发送一个http get请求,其中的参数也比较容易理解。
· url 服务器的url地址
· data 请求的参数可以采用String data:”xxx=xxx&xxx=xxx”的形式或者Object data:{“userId”:1}的形式
· header 设置请求的header
· method http的方法,默认为GET请求
· success 接口成功的回调
· fail 接口失败的回调
另外还有一个参数没有在代码里:
· complete 调用接口结束之后的回调,无论成功或者失败该接口都会被调用
超时的设置
在前文中已经提到了在app.js中设置networkTimeout可以设置四种类型网络访问的超时时间:
在前文中已经提到了在app.js中设置networkTimeout可以设置四种类型网络访问的超时时间:
"networkTimeout":{
"request": 10000,
"connectSocket": 10000,
"uploadFile": 10000,
"downloadFile": 10000
}
- 四、Tab分页
1.1 组件 tabBar
微信小程序提供了一个组件tabBar用来实现多tab分页功能。如果我们的小程序是一个多 tab 应用(客户端窗口的底部有tab栏可以切换页面),那么我们可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。
tabBar 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。
微信小程序提供了一个组件tabBar用来实现多tab分页功能。如果我们的小程序是一个多 tab 应用(客户端窗口的底部有tab栏可以切换页面),那么我们可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。
1.2 配置位置
微信小程序中认为整个页面分为 导航栏navigationBar,tab栏 tabBar 和 页面区域(就是在pages中配置的页面显示区域),所以tabBar的配置位于全局配置文件app.json 文件中。
"tabBar": {
"color": "#a9a9a9",
"selectedColor": "#1f1f1f",
"backgroundColor": "#fefefe",
"borderStyle": "white",
"list": [
{
"pagePath": "pages/main/main",
"text": "首页",
"iconPath": "image/icon_home.png",
"selectedIconPath": "image/icon_home_select.png"
},
{
"pagePath": "pages/aboutUs/aboutUs",
"text": "关于我们",
"iconPath": "image/icon_person.png",
"selectedIconPath": "image/icon_person_select.png"
}
] }
1.3 icon图标
对于每一个tab的icon,需要放置于本地工程内,经测试此处不支持网络图片。需在工程根目录下创建用于存放图片的文件夹,文件名随意,使用时需指定其相对路径。
五、轮播
组件 swiper
微信小程序原生就提供了轮播控件,在微信的文档中叫做 滑块视图容器。只需要简单的配置就可以实现轮播的效果。
属性 vertical ,其值接受Boolean型变量,默认值为false。
当不设置 vertical 属性,或者 vertical=”false” 时,指示点在组件下部,图片轮播从左至右,当设置 vertical=”true” 时,指示点在组件右部,图片轮播从下至上
注意: swiper是一个容器类视图,但是其中只能放置<swiper-item/>
组件,如放置其他节点,会被自动删除。
swiper-item
仅可放置在 swiper 组件中,宽高自动设置为100%。代表轮播中一帧的页面,通常以循环的方式加载到页面中。
代码如下:
<!--main.wxml-->
<view>
<swiper class="swiper_box" indicator-dots="{{indicatorDots}}" vertical="{{vertical}}"
autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" bindchange="swiperchange">
<block wx:for="{{images}}">
<swiper-item>
<image src="{{item.picurl}}" class="slide-image"/>
</swiper-item>
</block>
</swiper>
</view>
//main.js
//获取应用实例
var app = getApp()
Page({
data: {
indicatorDots: true,
vertical: true,
autoplay: true,
interval: 3000,
duration: 1000,
loadingHidden: false // loading
},
//事件处理函数
swiperchange: function(e) {
// 此处写 轮播 改变时会触发的 change 事件
},
onLoad: function() {
console.log('onLoad')
var that = this
//sliderList
wx.request({
url: 'http://huanqiuxiaozhen.com/wemall/slider/list',
method: 'GET',
data: {},
header: {
'Accept': 'application/json'
},
success: function(res) {
that.setData({
images: res.data
})
}
})
}
})
item单击事件
在 swiper-item 上绑定事件,通过 data 自定义标签绑定数据。然后在function中通过event拿到。
<!--main.wxml-->
<view>
<swiper class="swiper_box" indicator-dots="{{indicatorDots}}" vertical="{{vertical}}"
autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" bindchange="swiperchange">
<block wx:for="{{images}}">
<swiper-item bindtap="itemclick" data-id="{{item.id}}" data-name="{{item.name}}">
<image src="{{item.picurl}}" class="slide-image"/>
</swiper-item>
</block>
</swiper>
</view>
注意代码中的 data-id 和 data-name 均为自定义标签,然后可以在绑定事件的event中通过 id 和 name 拿到。
// 轮播item点击事件
itemclick: function(e) {
wx.showToast({
title: e.currentTarget.dataset.id + "",
icon: 'success',
duration: 2000
})
},
注意在绑定的function中可以通过event拿到对应的数据。如:e.currentTarget.dataset.id 对应wxml中的data-id
当然,还有另一种办法。不需要绑定事件,通过在每一个的 swiper-item 外面包上一个 a 标签,以超链接的方式跳转页面。
六、列表上拉加载下拉刷新
1.列表(本部分内容出入官方文档)
对于这个功能,微信小程序中并没有提供类似于Android中listview性质的控件,所以我们需要使用 wx:for 控制属性绑定一个数组,用数组中各项的数据重复渲染该组件,来达到列表的效果。
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
Page({
data: {
array: [{
message: 'foo',
}, {
message: 'bar'
}]
}
})
默认数组的当前项的下标变量名默认为index,数组当前项的变量名默认为item,当然也可以通过 wx:for-item 和 wx:for-index 指定。
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
wx:for也可以嵌套,下边是一个九九乘法表
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i">
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j">
<view wx:if="{{i <= j}}">
{{i}} * {{j}} = {{i * j}}
</view>
</view>
</view>
block wx:for
类似block wx:if
,也可以将wx:for用在<block/>
标签上,以渲染一个包含多节点的结构块。例如:
<block wx:for="{{[1, 2, 3]}}">
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
wx:key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 <input/>
中的输入内容,<switch/>
的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。
wx:key 的值以两种形式提供
1. 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
2. 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
示例代码:
<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch>
<button bindtap="switch"> Switch </button>
<button bindtap="addToFront"> Add to the front </button>
<switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;"> {{item}} </switch>
<button bindtap="addNumberToFront"> Add to the front </button>
Page({
data: {
objectArray: [
{id: 5, unique: 'unique_5'},
{id: 4, unique: 'unique_4'},
{id: 3, unique: 'unique_3'},
{id: 2, unique: 'unique_2'},
{id: 1, unique: 'unique_1'},
{id: 0, unique: 'unique_0'},
],
numberArray: [1, 2, 3, 4]
},
switch: function(e) {
const length = this.data.objectArray.length
for (let i = 0; i < length; ++i) {
const x = Math.floor(Math.random() * length)
const y = Math.floor(Math.random() * length)
const temp = this.data.objectArray[x]
this.data.objectArray[x] = this.data.objectArray[y]
this.data.objectArray[y] = temp
}
this.setData({
objectArray: this.data.objectArray
})
},
addToFront: function(e) {
const length = this.data.objectArray.length
this.data.objectArray = [{id: length, unique: 'unique_' + length}].concat(this.data.objectArray)
this.setData({
objectArray: this.data.objectArray
})
},
addNumberToFront: function(e){
this.data.numberArray = [ this.data.numberArray.length + 1 ].concat(this.data.numberArray)
this.setData({
numberArray: this.data.numberArray
})
}
})
2.下拉刷新
小程序页面集成了下拉功能,并提供了接口,我们只需要一些配置就可以拿到事件的回调。
1. 需要在 .json 文件中配置。(.json 文件的格式和 app.json与具体页面的.json文件的区别,前文已经讲过,有疑问的可以移步。) 如果配置在app.json文件中,那么整个程序都可以下拉刷新。如果写在具体页面的.json文件中,那么就是对应的页面,可以下拉刷新。
具体页面的.json文件:
{
"enablePullDownRefresh": true
}
app.json文件:
"window": {
"enablePullDownRefresh": true
}
2. 在js文件中添加回调函数
// 下拉刷新回调接口
onPullDownRefresh: function () {
// do somthing
},
3. 添加数据
通常情况下的下拉刷新操作,就是把查询条件重置,让页面显示最新的一页数据。下面是笔者demo中的下拉刷新回调接口的代码,同时也是一般情况下的操作流程。
// 下拉刷新回调接口
onPullDownRefresh: function () {
// 我们用total和count来控制分页,total代表已请求数据的总数,count代表每次请求的个数。
// 刷新时需把total重置为0,代表重新从第一条请求。
total = 0;
// this.data.dataArray 是页面中绑定的数据源
this.data.dataArray = [];
// 网络请求,重新请求一遍数据
this.periphery();
// 小程序提供的api,通知页面停止下拉刷新效果
wx.stopPullDownRefresh;
},
3 .上拉加载
同下拉刷新一样,小程序中也提供了用于上拉时回调的接口。官方文档中并没有很详细的介绍,经测试发现,上拉回调的接口并不需要额外的配置(下拉时需要在 .json文件中配置 "enablePullDownRefresh": true
),直接在页面滑动到底部时就能拿到回调。
1. 在js文件中添加回调函数
// 上拉加载回调接口
onReachBottom: function () {
// 我们用total和count来控制分页,total代表已请求数据的总数,count代表每次请求的个数。
// 上拉时需把total在原来的基础上加上count,代表从count条后的数据开始请求。
total += count;
// 网络请求
this.periphery();
},