微信小程序 - 入门指引

时间:2021-12-13 02:53:28

稍微整了整微信小程序,还是有不少问题的,做个小总结吧

和以往一样,本次项目也放到了 Github 中,欢迎围观 star ~

一、微信公众平台 - 小程序后台

1.申请小程序账号

官网注册

注册时所用的邮箱有限制(未注册过公众平台、开放平台、企业号、未绑定个人号的邮箱)

选择主体为个人或企业,按照流程注册

小程序的信息填写有次数限制,需要注意不要乱填(服务类目,名称,头像,介绍 等)

登录

2.设置

记住这两项 AppID 和 AppSecret,在开发时需要用到

大部分操作都需要管理员扫码验证

微信小程序 - 入门指引

配置好开发者,体验用户的相关权限

微信小程序 - 入门指引

设置 -> 基本设置 中配置好 基础库最低版本的设置

微信小程序 - 入门指引

设置 -> 开发者设置 -> 服务器域名中   配置好服务器域名,小程序才能正确地发起异步请求

微信小程序 - 入门指引

3.小程序社区

常见的问题可以 在 小程序社区 及 小程序论坛 及 小程序文档 查找答案

二、小程序开发者工具

使用文档  工具下载

1.安装

注意,小程序开发者工具与公众号开发者工具不能同时运行,不能安装在同一个目录中

为了能够兼容两者的使用,需要一些额外的操作

比如需要同时使用三个工具,先修改文件夹命名

微信小程序 - 入门指引

内部的exe可执行程序修改成对应的名称

微信小程序 - 入门指引

微信小程序 - 入门指引

在开始菜单中才能正确找到三个程序的快捷入口

微信小程序 - 入门指引

一般来说,开发者工具仅作为编译及调试使用,代码编辑建议使用自己的编辑器或IDE

开发者工具bug多多,如果发现失效的奇怪的问题,请重启开发者工具

常用快捷键:

Ctrl+B 编译

Ctrl+R 刷新

Ctrl+Shift+P 远程预览(项目需要提供AppID)

2.其他说明

2.1. 打开开发者工具,选择项目文件夹,自动识别为已有项目还是新建的项目

填写AppID 才能使用真机预览

微信小程序 - 入门指引

2.2. 小程序布局以iPhone6为基础

所以在移动设备模拟中 选用 iPhone6作为基准,再兼容其他设备

设备模拟与真机预览某些时候差异很大,别忘了在手机上调试

微信小程序 - 入门指引

2.3 建议的设置项

微信小程序 - 入门指引

微信小程序 - 入门指引

默认开发者工具中发起的异步请求仅在开发者工具中看到,如需使用Fiddler进行调试,需要手动设置代理

微信小程序 - 入门指引

2.4 项目配置

项目的设置,会自动同步到 project.config.json文件中

点开右侧详情,选中比较高的调试基础库版本

选用自带的ES6转ES5,代码补全压缩

开发时记得勾选不校验域名(防止访问失败),上线阶段记得取消勾选(校验域名可更安全)

微信小程序 - 入门指引

可点击切换编辑器的显示隐藏,快速调整右下开发者调试的窗口

微信小程序 - 入门指引

2.5 代码上传

2.5.1 先进行编译并远程预览

微信小程序 - 入门指引

2.5.2 再进行上传,管理员登录微信公众平台选择启用为体验版本,相关人员进行体验

微信小程序 - 入门指引

2.5.3 管理员选用体验版本上传作为审核

不可随意上传审核,多次审核不通过有惩罚机制

2.5.4 管理员选择审核通过的版本,发布为线上版本

三、小程序开发框架、代码结构

1.基础结构

文档

微信小程序 - 入门指引

文件的配置项

tabbar中的路径以及页面中的跳转路径,都必须在app.json的pages中配置好,其中分包的pages也要配置好

2.项目结构

小程序支持大部分ES6语法,但为了支持完整的ES6+语法,以及对原生的回调做优化,引入 wxPromise

基本支持小程序的所有API转换成 then catch  finally 的便捷语法,加上 wx.pro.即可  如

// 演示 wxPromise 的能力
wx.request({
url: 'test.php', //仅为示例,并非真实的接口地址
data: {
x: '' ,
y: ''
},
header: {
'content-type': 'application/json' // 默认值
},
success: function(res) {
console.log(res.data)
},
fail: function(e) {
console.log(e)
},
complete: function(e) {
console.log(e)
}
})
wx.pro.request({
url: 'test.php',
data: {},
method: 'GET',
header: {'content-type': 'application/json'}
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
}).finally(() => {
wx.hideLoading()
})

小程序不支持SCSS预编译的CSS,为了支持SCSS,所有需要引入构建工具进行编译

小程序自带了代码压缩,不过基本上只是对JS做了压缩,还需要压缩其他资源文件(WXSS、WXML等)

引入Gulp构建工具

项目参考 此Demo

目录结构

微信小程序 - 入门指引

src目录为源代码,gulpfile为 Gulp的任务配置,经过处理猴,将生成dist目录,在小程序开发者工具中打开此 dist目录即可

在sign目录下,执行 npm i 安装依赖包,然后运行 npm start 即可执行并监听,更新dist目录的内容,然后在 开发者工具中重新编译 Ctrl+B 即可看到效果(有时开发者工具出现奇怪问题的,就重启工具)

微信小程序 - 入门指引

src目录中主要为项目根文件,pages页面目录,assets资源目录

pages目录中的 嵌入的subPages目录用作分包目录,页面之外的其他资源文件或其他模块在assets目录中

app.json配置示例

{
"pages": [
"pages/index/index",
"pages/user/user",
"pages/wait/wait"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#1296db",
"navigationBarTitleText": "我来也",
"navigationBarTextStyle": "white"
},
"subPackages": [{
"root": "pages/subPages",
"pages": [
"signed/signed"
]
}],
"tabBar": {
"selectedColor": "#1296db",
"borderStyle": "white",
"list": [
{
"pagePath": "pages/index/index",
"text": "我要签到",
"iconPath": "./assets/imgs/sign.png",
"selectedIconPath": "./assets/imgs/sign_active.png"
},
{
"pagePath": "pages/wait/wait",
"text": "等候大厅",
"iconPath": "./assets/imgs/wait.png",
"selectedIconPath": "./assets/imgs/wait_active.png"
},
{
"pagePath": "pages/user/user",
"text": "个人中心",
"iconPath": "./assets/imgs/user.png",
"selectedIconPath": "./assets/imgs/user_active.png"
}
]
},
"debug": true
}

页面配置user.json配置示例

{
"navigationBarTitleText": "个人中心"
}

Gulp编译示例

微信小程序 - 入门指引

运行示例

微信小程序 - 入门指引

3. 项目框架

小程序开发,一般有三种方式

3.1 纯原生开发

3.2 基本使用原生开发,并使用构建工具进行一些简单构建

3.3 使用小程序开发框架

比较常用的框架为,wepy 和 mpvue

微信小程序 - 入门指引

两者都需要vue语法基础,无vue基础则有些障碍,相对来说 mpvue能更纯粹地使用以往开发Web的经验,wepy在小程序之上又有自己的一套规则

使用框架,并不是不再需要使用小程序原生的语法API

鉴于此,为了弥补原生不支持SCSS的不足,使用 3.2 做简单构建方案

不采用webpack的原因是webpack基于JS模块,通过配置入口模块做依赖打包,在小程序项目中Gulp工作流的方案更为合适

四、小程序基础语法、常见问题

1.基础用法

小程序的学习主要分为 框架  组件 API三个部分

框架为基础的语法结构

组件类似web中的HTML标签,web中的component

API为小程序中的可用JS方法

部分组件与API有版本兼容问题,需要注意

2. 常见问题

2.1 input组件中上方的图标按钮在真机中点击失效

input组件为原生组件,层级最高。focus 聚焦状态下点击上方的按钮时,会先触发失焦,再次点击按钮才生效

微信小程序 - 入门指引

解决办法,按钮置于input后面,背景做一些处理,与input区域的背景协调一致

微信小程序 - 入门指引

另外要注意,需要将按钮可点区域扩大,可以获得更好的使用体验

微信小程序 - 入门指引

2.2 image组件的大小适应问题

小程序中image默认为完全拉伸至填满image容器的scaleToFill 属性,有时会导致图片扭曲变形

常用的 mode 模式为 widthFix 宽度不变,高度自动变化,保持原图宽高比不变。需要先设置好宽度

另外,在引入小图标时,也要注意小图标受到image组件默认宽高320px*240px 的影响,会被拉伸。可手动设置宽高解决

2.3 部分小图标可使用自带的 icon组件

微信小程序 - 入门指引

2.4 如需要提供可选择可复制的文本 ,需使用 text组件 ,而不是 view 组件

2.5 Flex布局的使用

小程序中会大量使用到 Flex布局,要掌握好。优先使用此布局方案

2.6 rpx自适应单位的使用

小程序中引入了新的CSS单位 rpx(responsive pixel), 相对于px,它提供了自适应的能力,优先使用这个单位

微信小程序 - 入门指引

规定了以iPhone6屏幕(375px*667px)为基准,其设备像素比DPR为2,所以定义其屏幕宽度为 375px * 2 = 750rpx,相当于 1px == 2rpx  、1rpx == 0.5px

在以往web开发中,我们需要根据不同机型的屏幕宽度与DPR,手动计算不同的rpx值

但在小程序中,我们只需要以iPhone6为基准开发即可(设计稿也需要设计成iPhone6的750px宽度),设置好750px下某个元素应该是多少rpx,其他的转换工作无需考虑

2.7 文本垂直居中的处理

在小程序中文本和图片之前的垂直居中可能需要特殊处理, 以往web页面中可用 vertical-align: middle; 实现居中效果

但在小程序中的 image组件 和 text 组件的表现不太一样,看着不居中

微信小程序 - 入门指引

可以使用Flex布局居中的方式,父元素设置  display: flex;  align-items: center; 即可

微信小程序 - 入门指引

2.8 底部 tabbar图标与文本大小的自适应

小程序自带的 底部tabbar可自定义的程度不是很高,不同机型下可能会出现图标太大或文字太小的不同现象

解决方案:

使用自带tabbar,图标选用 81px * 81px ,注意图标不要撑满大小,需要留白,否则会偏大

微信小程序 - 入门指引

自定义tabbar,需要模拟原生tabbar的一些跳转时的固定效果,尽量保持和自定义的体验一致

可参考 一些Demo

2.9  页面跳转使用绝对路径,且需要在 pages 中配置好

如 跳转到某个页面

wx.navigateTo({
url: '/pages/subPages/signed/signed'
});

2.10 tabbar中配置的页面,需要使用 switchTab 才能跳转

同样的 switchTab 也只能跳转到 tabbar设置的页面

wx.switchTab({url:'/pages/user/user'});

<navigator class='goto-sign' open-type="switchTab" url='/pages/index/index'>
<image src="../../assets/imgs/sign_active.png" />
<text>前往签到</text>
</navigator> wx.redirectTo({url:'/pages/subPages/signed/signed'});

2.11 在WXSS中的背景图片不能设置为本地路径

仅支持作为 base64引入图片,或者使用网络地址的图片,或者使用 image组件引入图片

2.12 请求时的url参数需要设置为带 scheme(如 http)的绝对地址

且需要在微信工作平台设置好服务器域名

2.13 小程序的代码包限制为 2M 

可使用分包策略,单个包限制为2M,所有包限制为8M

能使用网络资源的就使用网络资源(比如图片、音频等),能压缩的就压缩,精简优化代码

分包方法:

假设对不需要初次就加载的页面 signed.wxml进行打包加载,对其进行分包

在 app.json中配置 subPackages

"subPackages": [{
"root": "pages/subPages",
"pages": [
"signed/signed"
]
}],
"tabBar": {
...
}

将该页面包放在 pages主页面目录下的 subPages 子页面目录即可

微信小程序 - 入门指引

跳转时记得把 这里的 subPages 路径也加上  /pages/subPages/signed/signed

2.14 过多地进行 setData 操作可能会导致性能下降

2.15 登录授权的兼容方案

以下仅涉及获取用户基本信息的部分,如要获取openID 手机号等 还需要发起请求让后端来解密处理 更多步骤

旧版本中一般直接使用JS进行调用

wx.getUserInfo({
success: function(res) {
console.log(res.userInfo)
}
})

微信小程序 - 入门指引

新版本中已逐渐不支持,直接调用会失效,应该改用 button组件引导用户启用授权

微信小程序 - 入门指引

点击按钮后再获取信息

微信小程序 - 入门指引

<view class='user__info'>
<button wx:if="{{!hasUserInfo}}" open-type='getUserInfo' bindgetuserinfo='getUserInfo'>
<image class='user__wx' src="../../assets/imgs/wx.png" mode='widthFix' />
<text>微信授权登录</text>
</button>
<block wx:else>
<image class="user__avatar" src="{{avatar}}"/>
<view >{{nickName}}</view>
</block>
</view>

有信息的就直接显示信息,否则提示用户点击按钮授权

点击后将触发 getUserInfo回调,e.detail中携带了 与 wx.getUserInfo 相同的返回信息

将用户信息保存到本地缓存

data: {
hasUserInfo: app.globalData.userInfo.hasUserInfo,
avatar: app.globalData.userInfo.avatar,
nickName: app.globalData.userInfo.nickName
},
...
getUserInfo(e) {
if (!e.detail.userInfo) {
return;
}
app.globalData.userInfo = {
hasUserInfo: true,
avatar: e.detail.userInfo.avatarUrl,
nickName: e.detail.userInfo.nickName
}
wx.setStorage({
key: 'userInfo',
data: app.globalData.userInfo
});
this.setData({
hasUserInfo: app.globalData.userInfo.hasUserInfo,
avatar: app.globalData.userInfo.avatar,
nickName: app.globalData.userInfo.nickName
});
}

2.16 上传文件

目前仅支持上传图片及小视频

仅支持一次上传一个文件,多个文件需循环上传

需考虑全部上传成功才继续操作,可使用 promise.all结合await/async 异步处理

如 上传图片成功后才提交数据

async uploadFaces() {
let p = [];
(this.data.face || []).forEach(item => {
p.push(new Promise((resolve, reject) => {
wx.pro.uploadFile({
url: 'http://xxx',
filePath: item,
name: 'cover',
formData: {
_csrf: 'RktCQ3daWDJ3Sk1aSE9ucikRJRYcLhoFODo1Yx4AACgLBDsTBSwAYS59fGsxJ1offf'
},
header: {
'Cookie': 'PHPSESSID=95nno109b17gbfb852tpf4mke455',
'content-type': 'multipart/form-data'
}
}).then(rs => {
let data = typeof rs.data === 'string' ? JSON.parse(rs.data) : rs.data;
if (!data.status) {
reject(rs);
} else {
resolve(rs);
}
console.log(rs);
}).catch(e => {
reject(e);
console.log(e);
});
}));
});
await Promise.all(p);
},
submitData(data) {
let that = this;
console.log(data);
...
} ... if (rs.confirm) {
let uploadFaceloading = wx.showLoading({
title: '上传中'
}); // 先上传图片
that.uploadFaces()
.then((rs) => {
console.log('uploadSuccess', rs); // 再提交数据
that.submitData(e.detail.value);
}).catch(e => {
wx.showToast({
title: '上传失败',
icon: 'none'
});
console.log('uploadFail', e);
}).finally(rs => {
wx.hideLoading(uploadFaceloading);
});
}

2.17  获取本地图片 wx.chooseImage 等相关的API,会触发页面的 onHide/onShow

开始选择,直到选择完毕,相关的触发流程

微信小程序 - 入门指引

所以在onShow或onHide中需要处理一些数据时,要关注这个问题

在app.globalData中设置一个标志位,由其他页面跳转进来onShow时获取到正确的标志位(即其他页面卸载/隐藏时 将该标志为置位),chooseImage 选择后不置位

使用一些获取页面栈的API,来判断当前页面的信息(如 getCurrentPages() ,只是能够判断出来的几率不是很大)

2.18 获取用户坐标位置

使用 wx.getLocation 能够获取用户坐标的经纬度,我们还需要将其转换为可识别的城市信息,需要使用第三方API(比如腾讯地图,百度地图等)来解析坐标

微信小程序 - 入门指引

使用腾讯位置服务,先注册登录,生成属于自己的 KEY值用于传值,需要启用 WebServiceAPI

微信小程序 - 入门指引

查看相关文档下载 JDK,然后引入

在获取到经纬度之后,调用

// app.js
let QQMapWX = require('./assets/js/qqmap-wx-jssdk.min.js'); App({
onLaunch: function() {
let userInfo = wx.getStorageSync('userInfo');
this.globalData.qqmapsdk = new QQMapWX({
// 输入对应的key
key: '...'
});
}, globalData: {
qqmapsdk: null
}
}); // index.js
let app = getApp(); Page({
onReady() {
wx.pro.getLocation({
type: 'wgs84'
}).then(res => {
console.log(res);
// 获取当前位置
app.globalData.qqmapsdk.reverseGeocoder({
location: {
latitude: res.latitude,
longitude: res.longitude
},
success: (addressRes) => {
let city = addressRes.result.address_component.city;
console.log(addressRes.result.address_component, city);
// 匹配当前坐标,设置城市
if (city) {
let groupSelected = this.data.group.find(item => {
return city.includes(item);
});
groupSelected && this.setData({
groupSelected: groupSelected
});
}
},
fail: (e) => {
console.log(e);
}
});
}).catch(e => {
console.log(e);
});
} })

也可以手动设置经纬度进行测试,在开发者工具中

微信小程序 - 入门指引

可以使用百度地图拾取坐标系统 查询某地的坐标,用作测试

微信小程序 - 入门指引

首次调用时会询问用户授权,如果用户允许了,接下去就不再询问。如果拒绝,则将一直拒绝。

大部分授权的询问机制是差不多的。

2.19 关于授权

微信小程序涉及很多授权相关的东西,基础的信息可以直接使用API获取,敏感数据需要通过后端发起API来解析

在微信开发者工具中,可以在这里清除授权信息(远程调试的手机上也会被清除),用以反复测试授权的情况

微信小程序 - 入门指引

微信小程序 - 入门指引

在手机上,可以点击小程序右上角的.. ,查看关于小程序

微信小程序 - 入门指引

微信小程序 - 入门指引

微信小程序 - 入门指引

即可在这个页面的授权列表中开启或关闭

如果用户之前已经拒绝授权,调用相关API时将直接失败,不会再弹出授权窗口

这时,可以考虑使用 wx.openSetting ,将会跳转到这个授权列表页,让用户先手动设置

// 打开授权设置窗口,进行手动授权
wx.pro.openSetting({})
.then(rs => {
console.log(rs);
}).catch(e => {
console.log(e);
});

也可以使用 wx.authorize 来指定哪种授权,不过如果之前用户拒绝过,将在一段时间之内一直返回失败的信息,所以还是很鸡肋的..

// 获取用户的授权状态列表
wx.pro.getSetting({})
.then(rs => {
console.log(rs);
// 查询位置信息是否已允许授权
if (!rs.authSetting['scope.userLocation']) {
// 请求授权获取用户位置
wx.pro.authorize({
scope: 'scope.userLocation'
})
.then(rs => {
console.log(rs);
}).catch(e => {
console.log(e);
});
}
}).catch(e => {
console.log(e);
});

其他相关的API

获取用户的登录状态,在调用某些API时,需要先调用此API,目前还不得而知

// 获取用户的登录状态
wx.pro.login({})
.then(rs => {
console.log(rs);
}).catch(e => {
console.log(e);
});