前言
对Vue开发有一定了解,对微信小程序比较感兴趣,想要理解其开发流程,这篇文章可以帮助你少踩一些坑,实现并发布自己的第一个微信小程序。
准备工作
登陆微信公众平台-小程序:https://mp.weixin.qq.com/cgi-bin/wx,完成申请与注册,生成一个重要的AppID(小程序唯一身份证:开发→开发设置获取)。
-
安装小程序开发工具:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html,界面使用类其他编译器,点击上方编译可在模拟器查看效果,点击预览可用手机扫码查看效果,如图:
-
创建第一个小程序项目,填入AppID。选择云开发可使用云函数、云数据库、云存储功能,如图:
小程序详细开发文档:https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart/(遇到问题一定要看文档!看文档!看文档!重要的事情说3遍!!!详细易懂,少走弯路)
一. 小程序代码构成
1)文件目录:
.
├── cloudfunctions # 云开发函数
│ ├── login //登陆文件夹
│ │ ├── index.js //登陆云函数
│ │ └──package.json //npm包依赖
│ └── movielist //获取电影列表文件夹
├── miniprogram #本地开发目录
│ ├── style //静态wxss文件
│ ├── fonts //字体图标文件
│ ├── images //图片
│ ├── components //存放公共组件库
│ ├── utils //全局js方法
│ │ └── common.wxs //js处理方法
│ ├── pages //各页面
│ │ ├── movie //电影列表
│ │ │ ├── movie.js
│ │ │ ├── movie.json
│ │ │ ├── movie.wxml
│ │ │ └── movie.wxss
│ │ └── detail //电影详情
│ │ ├── detail.js
│ │ ├── detail.json
│ │ ├── detail.wxml
│ │ └── detail.wxss
│ ├── app.js //全局注册小程序对象
│ ├── app.json //全局配置
│ ├── app.wxss //全局样式
│ └── package.json //npm配置文件
├── project.config.json #项目配置文件
└── README.md #README
2).json 后缀的 JSON 配置文件:
- app.json全局配置小程序的页面路由,底部tab,顶部标题等。
-
page.json页面配置可以声明不同于全局的配置,只在该页面生效,还可引入组件。
pages字段控制当前所有页面路径,第一个默认为首页;
window字段控制窗口背景颜色,标题等;
tabBar控制分成几个tab页,list数组长度2~5,参数有图标、字体颜色、页面路由。
<!-- app.json -->
//全局配置文件
"pages": [
"pages/movie/movie",//第一个默认为首页
"pages/profile/profile",
"pages/detail/detail"
],
"window": {
"backgroundColor": "#F6F6F6",//下拉背景颜色
"backgroundTextStyle": "light",//下拉字体样式
"navigationBarBackgroundColor": "#00B51D",//窗口头部背景色
"navigationBarTitleText": "最新电影",//窗口头部文案
"navigationBarTextStyle": "white"//窗口头部字体颜色
},
"tabBar": {
"color": "#000000",//tab栏默认字体颜色
"selectedColor": "#E54847",//tab栏选中字体颜色
"list": [{
"pagePath": "pages/movie/movie",//tab路径
"text": "电影",//tab栏文案
"iconPath": "images/film.png",//默认图标路径
"selectedIconPath": "images/film-actived.png"//选中图标路径
},{
"pagePath": "pages/profile/profile",
"text": "我的",
"iconPath": "images/profile.png",
"selectedIconPath": "images/profile-actived.png"
}]
},
<!-- detail.json -->
//子页面配置文件
{
"usingComponents": {//注册vant-ui插件
"van-button": "vant-weapp/button",//按钮组件
"van-rate": "vant-weapp/rate",//评分组件
"van-icon": "vant-weapp/icon"//图标组件
},
"navigationBarBackgroundColor": "#333",//子页面标题背景色
"navigationBarTextStyle": "white",//子页面字体颜色
"navigationBarTitleText": "电影详情",//子页面标题
"backgroundColor": "#eee",//子页面下拉刷新背景色
"backgroundTextStyle": "dark",//子页面下拉刷新字体色
"enablePullDownRefresh": true//子页面下拉刷新
}
3).wxml 后缀的 WXML 模板文件:
主要控制页面结构,开发模式为MVVM可参考Vue,注意如下:
- div,span等标签换为了view,text;
- 微信提供了一些现成组件:轮播图、日历、进度条等等,也可使用UI库vant-weapp。
- 在wxml文件中不能使用js方法,需在小程序脚本语言wxs文件中(不允许引入js文件)定义好处理数据的函数,然后在wxml中引入可使用。
<!-- common.wxs -->
var filter = {
arrJoin: function(value){ return value.join('/') },
formatDate: function(value){
var date = getDate(value) return date.getFullYear() + '年' + date.getMonth() + '月' + date.getDate() + '日'
} }
module.exports={ arrJoin: filter.arrJoin, formatDate: filter.formatDate }
<!-- movie.wxml -->
<wxs module="filter" src="../../utils/common.wxs"></wxs>
<view class="movie" wx:for="{{movieList}}" wx:key="{{index}} wx:for-item="detailList"">
...
<!--调用wxs文件中的数组分割方法-->
<view>类型:{{filter.arrJoin(detailList.genres)}}</view>
<!--调用wxs文件中的时间格式化方法-->
<text class="tag-text">{{filter.formatDate(detailList.created_at)}}</text>
...
<!--使用按钮和评分组件-->
<van-rate value="{{detailList.rating.average}}" size="12" void-color="#999" void-icon="star" />
<van-button icon="like-o" type="primary" size="small">想看</van-button>
...
</view>
4).wxss 后缀的 WXSS 样式文件:
提供了新的尺寸单位rpx(可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素)。推荐使用iPhone6为设计稿,单位之间好换算,字体一般用px。
设备 | rpx换算px (屏幕宽度/750) | px换算rpx (750/屏幕宽度) |
---|---|---|
iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
/* pages/movie/movie.wxss */
@import '../../style/common.wxss'; /* 引入公共样式 */
.movie{
height: 420rpx;
display: flex;
border-bottom: 1rpx solid #eee;
padding: 20rpx;
color: #666;
}
.mv-img{
height: 100%;
width: 300rpx;
margin-right: 20rpx;
}
...
5).js 后缀的 JS 脚本逻辑文件:
注意事项:
- 点击事件不能在方法中直接传参数,需要data-id="id"定义,通过e.currentTarget.dataset.id获取;
- 给data中数据赋值时需this.setData({id: e.currentTarget.dataset.id}),获取值方式为this.data.id。
<!--movie.wxml-->
...
<view class="collect-item" bindtap="gotoDetail" data-movieid="{{item.id}}">
...
<!--movie.js-->
getMovie: function(){//获取电影列表,从云函数movielist获取
wx.showLoading({//调用微信加载组件
title: '加载中',
})
wx.cloud.callFunction({//请求云函数
name: 'movielist',
data: {
start: this.data.movieList.length,
count: 10
}
}).then(res=>{
console.log(JSON.parse(res.result).subjects)
this.setData({//将返回结果赋值给movieList
movieList: this.data.movieList.concat(JSON.parse(res.result).subjects)//数组拼接
})
wx.hideLoading()//返回结果关闭加载
}).catch(err=>{
console.log(err)
wx.hideLoading()//返回错误关闭加载
})
},
gotoDetail: function (e) {//跳转至新页面
wx.navigateTo({
url: `../detail/detail?movieid=${e.currentTarget.dataset.movieid}`,
})
},
二、使用npm安装第三方插件
- 右键点击项目在终端打开,执行npm init初始化package.json文件;
- 执行npm install XX --production;
- 勾选 详情->本地设置→使用npm模块;
- 点击工具→构建npm,即可在项目中使用;
三、微信原生API
可以方便的调起微信提供的能力,列举一些常用API:
- wx.navagateTo:保留当前页面,跳转到除了tabbar的其他页面,最多打开5个页面,可返回上一页;
- wx.redirectTo:关闭当前页面,跳转到除了tabbar的其他页面;
- wx.switchTab:跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面;
- wx.showToast:显示消息提示框,可设置延时消失;
- wx.showLoading:显示 loading 提示框。需主动调用 wx.hideLoading 才能关闭提示框;
- wx.request:发起HTTP网络请求;
- wx.chooseImage:从本地相册选择图片或使用相机拍照,视频/音频/文件同理;
- wx.getLocation:获取当前的地理位置、速度;
- wx.chooseLocation:打开地图选择位置,可获取目标经纬度和详细地址;
- wx.getUserInfo:获取用户信息,用户昵称、性别、头像、国家城市、语言等;
- wx.getWeRunData:获取用户过去30天微信运动步数;
- wx.scanCode:调起客户端扫码界面进行扫码;
- wx.makePhoneCall:拨打电话;
......
三、云开发
1)云数据库:
云开发提供了一个 JSON 数据库,数据库中的每条记录都是一个 JSON 格式的对象。一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条记录,记录的格式是 JSON 对象。支持导入导出。
// 1. 获取数据库引用
// collection 方法获取一个集合的引用
const db = wx.cloud.database()
//2. 构造查询语句
// get 方法会触发网络请求,往数据库取数据
// where 方法传入一个对象,数据库返回集合中字段等于指定值的 JSON 文档。API 也支持高级的查询条件(比如大于、小于、in 等)
db.collection('movie-collect').where({
_openid: res.result.openid
}).get().then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
// 3. 构造插入语句
// add 方法会触发网络请求,往数据库添加数据
db.collection('user').add({
data: {
name: 'ywbj',
age: 20
}
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
},
// 4. 构造更新语句
// update 方法会触发网络请求,往数据库更新数据(doc中为唯一id)
db.collection('user').doc('dc9a49695da03b0f023d6cfd2fa15012').update({
data: {
age: 18
}
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
},
// 5. 构造删除语句
// delete 方法会触发网络请求,使数据库删除数据(注意:在小程序中只能删除单条数据,批量删除需在云函数中操作)
db.collection('user').where({
name: 'ywbj'
}).remove()
.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
},
2)云存储:
云开发提供了一块存储空间,提供了上传文件到云端、带权限管理的云端下载能力,开发者可以在小程序端和云函数端通过 API 使用云存储功能。在小程序端可以分别调用 wx.cloud.uploadFile 和 wx.cloud.downloadFile 完成上传和下载云文件操作。
//上传文件
wx.chooseImage({// 让用户选择一张图片,生成临时图片路径
success: chooseResult => { // 将图片上传至云存储空间
wx.cloud.uploadFile({ // 指定上传到的云路径
cloudPath: 'my-photo.png', // 指定要上传的文件的小程序临时文件路径
filePath: chooseResult.tempFilePaths[0],
success: res => {
console.log('上传成功,返回文件ID', res.fileID)
},
})
}
})
//下载文件
wx.cloud.downloadFile({
fileID: '', // 文件 ID
success: res => { // 返回临时文件路径 console.log(res.tempFilePath) },
fail: console.error
})
3)云函数:
云函数是一段运行在云端的代码,无需管理服务器,在开发工具内编写、一键上传部署即可运行后端代码。可将功能相同的函数封装并上传至云函数统一调用,另外使用云函数发送请求的好处,不受5个可信域名限制,无需备案。发请求需npm安装request-promise并引入:https://github.com/request/request-promise。
<!--movielist/index.js-->// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
var rp = require('request-promise')
// 云函数入口函数,假设已有一个获取电影列表的接口
exports.main = async (event, context) => {
return rp(`http://api.douban.com/v2/movie/in_theaters?apikey=0df993c66c0c636e29ecbb5344252a4a&start=${event.start}&count=${event.count}`)
.then(res => {
return res
})
}
<!--movie.js-->
wx.cloud.callFunction({
name: 'movielist',
data: {
start: this.data.movieList.length,
count: 10
}
})