介绍
微信小程序的开发模式,和手机App的中间件模式开发非常相似(比如 Appcan ),都是客户端开发,都需要掌握客户端API,都需要使用服务端接口等等。区别在于小程序的客户端API是基于微信提供的,包括一些特别要求,服务端接口需要https啊、登录授权需要基于微信开放数据啊等等。
简单来说,小程序就是客户端标签(.wxml)+样式(.wxss)来显示用户界面,然后使用客户端脚本(.js)来进行与服务端接口数据交互。发展到今天,已经有很多成熟的组件、模板供我们使用,在需要时适当的应用即可。
开发准备
成为开发者
成为开发者,可进入 https://mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN 完成注册,按照指引填写信息和提交相应的资料,就可以拥有自己的小程序帐号。
这里有2种角色,一个是个人版,一个是企业版。企业版比个人版要多一些功能,比如支付接口等等。一般我们申请个人版就可以满足大多数要求。
开发工具
微信开发工具,点击下载,目前支持win32、win64、mac系统,下载后可进行公众号和小程序开发。
这里要注意,每个小程序账户只能绑定一个项目,通过appid进行创建。如果需要导入其它人的demo,为了方便可以使用测试号。
进入开发工具,左上区域主要有三个核心能力:
模块 | 说明 |
---|---|
模拟器 | 主要是展示效果,每次项目编译后,模拟器自动刷新显示最新效果。 |
编辑器 | 代码编辑区,编写页面、脚本、样式等。 |
调试器 | 主要调试脚本运行日志、网络请求等,可以理解为Google Chrome的开发者工具。 |
如果是开发调试阶段,需要在项目设置中,选中 不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书 ,这样就可以局域网来访问我们的服务接口。设置位置: 对开发工具有了大致的了解,那么就可以开始创建一个工程了。
快速入门
项目结构
应用结构
创建好第一个工程后,来看下默认代码结构:
目录 | 说明 |
---|---|
pages | 存放所有页面,可以根据模块自定义目录及子目录存储。 |
utils | 存放工具类库,如第三方的脚本库。 |
app.js | 应用全局JS脚本 |
app.json | 应用全局配置 |
app.wxss | 应用全局样式 |
project.config.json | 项目配置文件,包括appid、应用名称等等。 |
我们创建的页面,都存放到pages里面,建议根据应用模块分类,创建目录及子目录进行存放页面。我们发现,工程结构中没有图片资源存放的目录,这时建议在pages同级目录创建一个images目录,来存放图片资源。下图是一个默认的项目结构截图:
页面结构
页面结构包括如下文件:
.json
后缀的 JSON 配置文件;.wxml
后缀的 WXML 模板文件;.wxss
后缀的 WXSS 样式文件;.js
后缀的 JS 脚本逻辑文件。
首先说明一下,每个页面最多可以有这4个文件,最少要有一个.wxml
文件。
其中 .json
负责存储页面配置, .wxml
负责显示内容,.wxss
负责显示样式,.js
负责页面事件交互。
网络请求
好了,对一个小程序项目有了初步的了解,那么客户端需要有业务逻辑能力(比如你想查询一个数据列表,呈现到客户端,你想提交一个订单等等),肯定是需要通过网络请求我们的业务系统接口,实现一定的业务逻辑。
小程序的网络请求说明在 官方API 里面可以看到详细说明,里面介绍了很多种请求类型, request
、 uploadFile
、 Socket
等等,我们最常用的应该就是 request
了,这里以 request
为例,实现一个最普通的 http
请求。
wx.request({
url: 'http://x.x.x.x/mp/api/banner/show', //接口地址
data: {
p1: '' //接口参数
},
header: {
'content-type': 'application/json' // 默认值
},
success: function(res) {
console.log(res.data)
}
})
以上是官网例子,那么这里说明一点,我们一个小程序应用肯定是有N多个页面,所以也会写N多个请求地址,所以建议把地址的域名部分统一存储起来,防止域名变更,导致需要修改所有页面里的url地址。
那么应该存储在哪里呢? 可以将域名存储在全局的js文件里面,app.js,由于我是本地环境存储的ip,正式部署肯定存储域名了。
//app.js
App({
data: {
app_server: "http://x.x.x.x"
},
...
然后在每个页面请求地址里这样获取即可:
wx.request({
url: getApp().data.app_server + '/mp/api/banner/show', //接口地址
data: {
p1: '' //接口参数
},
...
⭐ Tip:网络请求前提条件,服务器的接口必须使用HTTPS请求,但是我们开发环境下,实现HTTPS请求比较麻烦,微信开发工具里面有个设置,不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书(上面开发工具中有提到)选中即可。
数据绑定
Ok,那么通过网络请求的数据,如果请求的是一个数据列表(返回Json格式),需要动态的显示在 .wxml
文件中。这里,我们需要预先定义页面数据变量,需要在Page——data里面定义,如下:
Page({
/**
* 页面的初始数据
*/
data: {
menus: [],
loadMore: 0,
pageNum: 1,
pageSize: 4
},
...
定义好的数据变量,在加载函数中进行网络请求,请求结果给数据变量赋值即可。如下代码:
Page({
data: {
menus: [] //定义空数组变量
},
/**
* 加载菜单
*/
loadMenus: function () {
var that = this; //小技巧,把当前页面变量赋值给that,防止网络请求里使用this的冲突。
wx.request({
url: getApp().data.app_server+'/mp/ui/menu/get-data',
header: {
'content-type': 'application/json'
},
success: function(res) {
that.setData({
menus: res.data
});
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.loadMenus();
},
...
})
这段代码,主要有1点需要补充下说明:
var that = this;
这样定义,适用在wx.request请求成功里面,给页面变量赋值使用(因为在wx.request里面也有this变量);- 给变量赋值,使用that赋值即可。
页面的变量通过网络请求动态赋值后,就可以应用在模板文件( .wxml )中了,即数据绑定。
<view class='station-container'>
<view class='station-wrapper-four' wx:for='{{menus}}' wx:key='{{index}}'>
<view class='menu' bindtap='menuHandle' data-url='{{item.menuUrl}}'>
<view class='img-wrapper'>
<image src='{{item.imgUrl}}'></image>
</view>
<view class='text'>
{{item.desc}}
</view>
</view>
</view>
</view>
通过 wx:for
标签来遍历 menus
数组进行数据动态绑定,最终展示给用户端。
⭐ Tip:数据绑定、列表渲染、条件渲染等wxml标签,更多可阅读官网文档的视图层/WXML部分,点击查看。
页面参数传递
页面导航
页面参数传递,就会想到页面吉之间如果跳转,一个页面打开其它页面,在HTML中叫 超链接
,而在小程序里叫 导航
组件,详细文档查阅 官方文档。在 .wxml
中的例子:
<view class="btn-area">
<navigator url="../../redirect/index" open-type="redirect" >在当前页打开</navigator>
</view>
如果想在JS事件里面,通过脚本来打开其它页面,可以通过 导航
相关的API实现,官网地址。在 .js
中的例子:
/**
* 点击菜单跳转事件
*/
menuHandle: function (e) {
//得到url页面地址
var menuUrl = e.currentTarget.dataset.url;
//跳转到指定页面地址
wx.navigateTo({
url: menuUrl
})
}
参数传递与接收
参数传递,比如一个数据列表页面,点击某个记录,跳转到详情页面,则需要传递记录ID参数,如下JS示例,项目列表页面(pages/project/project)绑定了点击事件,点击后进入详情页面:
bindDtap: function (e) {
var id = e.currentTarget.dataset.id;
//点击进入项目详情
wx.navigateTo({
url: 'project-item/project-item?id=' + id
})
}
示例截图:
项目详情页面(pages/project/project-item/project-item),可以在JS文件里onLoad函数中接收参数:
var $ = require('../../../utils/ajax.js');
Page({
/**
* 页面的初始数据
*/
data: {
item:{},
image_url:""
},
/**
* 加载详情
*/
loadDetails: function (id) {
var that = this;
$.post({ url: getApp().data.app_server + '/mp/project/get-details',
data:{id:id}
}).then((res) => {
if (res.statusCode == 200) {
that.setData({
item: res.data,
image_url: getApp().data.app_server+res.data.filePath
});
}
}).catch((err) => {
console.log(err);
});
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.loadDetails(options.id);
},
......
示例截图:
表单验证
表单,即提交数据的载体,与我们常规web开发中的form基本一样,也是通过form标签定义表单,input标签定义文本域等等,官网文档。
说到表单,微信有个weui的样式库,可以参考引用此库作为小程序表单默认样式,详见:点击查阅。下面是一个简单的weui表单样式Demo截图:
.wxml
代码,定义了2个input文本:
<view class="page" xmlns:wx="http://www.w3.org/1999/xhtml">
<form bindsubmit="formSubmit" bindreset="formReset">
<view class="page__hd">
<view class="icon_sp_area">
<icon type="success_no_circle" size="23"></icon>
手机验证 ——
<icon type="circle" size="23"></icon>
完成登录
</view>
</view>
<view class="page__bd">
<view class="weui-cells weui-cells_after-title">
<view class="weui-cell weui-cell_input">
<view class="weui-cell__hd">
<view class="weui-label">手机号</view>
</view>
<view class="weui-cell__bd">
<input name="tel" class="weui-input" placeholder="请输入手机号"/>
</view>
</view>
<view class="weui-cell weui-cell_input weui-cell_vcode">
<view class="weui-cell__hd">
<view class="weui-label">验证码</view>
</view>
<view class="weui-cell__bd">
<input name="vcode" class="weui-input" placeholder="请输入验证码" />
</view>
<view class="weui-cell__ft">
<view class="weui-vcode-btn">获取验证码</view>
</view>
</view>
</view>
<view class="weui-btn-area">
<button class="weui-btn" formType="submit" type="primary" >确定</button>
</view>
</view>
</form>
<loading hidden="{{submitHidden}}">
正在提交...
</loading>
</view>
那么表单验证的js代码如下:
var $ = require('../../../utils/ajax.js');
Page({
/**
* 页面的初始数据
*/
data: {
submitHidden:true
},
/**
* 提交数据
*/
formSubmit:function(e){
var that = this;
var warn = "";//弹框时提示的内容
var flag = true;//判断信息输入是否完整
if (e.detail.value.tel == "") {
warn = "请填写您的手机号!";
} else if (e.detail.value.vcode == "") {
warn = "请填写验证码!";
}else{
flag=false;//若必要信息都填写,则不用弹框,且页面可以进行跳转
that.setData({
submitHidden: false
})
//console.log('form发生了submit事件,携带数据为:', e.detail.value);
this.doLogin(that, e.detail.value);
}
//如果信息填写不完整,弹出输入框
if (flag == true) {
wx.showModal({
title: '提示',
content: warn
})
}
},
......
效果图:
通过模式窗口来进行提示,当然 weui
还有其它表单验证表现形式,需要自己去探索。
作者: Zealon
崇尚简单,一切简单自然的事物都是美好的。