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

和以往一样,本次项目也放到了 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);
});

微信小程序 - 入门指引的更多相关文章

  1. 天河微信小程序入门《四》:融会贯通,form表单提交数据库

    天河在阔别了十几天之后终于又回来了.其实这篇文章里的demo是接着(天河微信小程序入门<三>)后面就做了的,但是因为最近在做别的项目,所以就偷懒没有发出来.放到今天来看,从前台提交数据到数 ...

  2. 天河微信小程序入门《三》:打通任督二脉,前后台互通

    原文链接:http://www.wxapp-union.com/forum.php?mod=viewthread&tid=505&extra=page%3D1 天河君在申请到https ...

  3. 天河微信小程序入门:阿里云tomcat免费配置https

    天河君在第一时间通过了微信小程序验证,开启了我的微信小程序之旅.因为天河君之前是一名后端狗,对前端不是很了解,所以几乎可以认为是从零开始学做微信小程序.也希望有志在微信小程序方向做点事情的朋友能够和我 ...

  4. 我的微信小程序入门踩坑之旅

    前言 更好的阅读体验请:我的微信小程序入门踩坑之旅 小程序出来也有一段日子了,刚出来时也留意了一下.不过赶上生病,加上公司里也有别的事,主要是自己犯懒,就一直没做.这星期一,赶紧趁着这股热乎劲,也不是 ...

  5. 微信小程序入门正确姿势(一)

    [未经作者本人同意,请勿以任何形式转载] >>>前言 这是 [认真学编程] 系列的 第4篇 文章(微信小程序入门系列),欢迎点赞分享.写留言,这些都是对我最好的支持. 本系列适合有一 ...

  6. 微信小程序入门篇

    微信小程序入门篇: 准备工作 IDE搭建 就不多说了,没有内测码去下载个破解版吧,我用了一下,学习完全够了!IDE破解版+安装教程 图片发自简书App 知识准备 JavaScrip还是要看看的,推荐教 ...

  7. 微信小程序入门案例

    本文通过具体的实例记录微信小程序的入门知识. 1.特点 不需要安装 依赖微信应用 更接近原生APP 丰富的框架及API可达到快速开发的目的 2.工具使用 在开发的过程中可以使用微信开发者工具,更加直观 ...

  8. 从零开始的微信小程序入门教程(一)

    之前说要和同事一起开发个微信小程序项目,现在也在界面设计,功能定位等需求上开始实施了.所以在还未正式写项目前,打算在空闲时间学习下小程序.本意是在学习过程中结合实践整理出一个较为入门且不是很厚的教程, ...

  9. 微信小程序入门与实战 常用组件API开发技巧项目实战*全

    第1章 什么是微信小程序? 第2章 小程序环境搭建与开发工具介绍 第3章 从一个简单的“欢迎“页面开始小程序之旅 第4章 第二个页面:新闻阅读列表 第5章 小程序的模板化与模块化 第6章 构建新闻详情 ...

随机推荐

  1. [Django] Window上通过IIS发布Django网站

    网上的教程坑实在多,以下是本人亲测通过的: 需要解决的问题: 1.使用 python manage.py runserver 来运行服务器,只适用测试环境中使用,正式发布的服务,需要一个可以稳定而持续 ...

  2. SPARK安装三:SPARK集群部署

    使用2.3.0版本,因为公司生产环境是这个版本 一.下载安装 cd /opt wget https://archive.apache.org/dist/spark/spark-2.3.0/spark- ...

  3. 常用screen参数

    摘自:https://www.cnblogs.com/webnote/p/5749675.html screen -S yourname -> 新建一个叫yourname的sessionscre ...

  4. 第二阶段第一次spring会议

    昨天我们讨论了改进方法,打算建立数据库. 今天我对39个组发表了建议以及总结了改进意见和改进方案. 明天我将对软件添加回收站.

  5. Python基础(六)

  6. 独一无二 hortonworks spark 源码编译教程

    hortonworks的源码在github上能找到! https://github.com/hortonworks/spark2-release 找到对应版本release源码后下载到本地 在wind ...

  7. C# Autofac集成之Framework WebAPI

    Web API 2集成需要Autofac.WebApi2 NuGet包. Web API集成需要Autofac.WebApi NuGet包. Web API集成为控制器,模型绑定器和操作过滤器提供了依 ...

  8. Thinking in Java Chapter 14

    From Thinking in Java 4th Edition RTTI(Run-Time Type Information),运行时类型信息,使得你可以在程序运行时发现和使用类型信息.对RTTI ...

  9. electron 使用 node-ffi 调用 C++ 动态链接库(DLL)

    一.为什么需要使用DLL 需要使用系统 API 操作或扩展应用程序: 需要调用第三方的接口API,特别是与硬件设备进行通信,而这些接口 API 基本上都是通过 C++ 动态链接库(DLL)实现的: 需 ...

  10. 三种方法在当前目录下打开cmd命令窗口

    概述 运行npm的时候,每次都要cd到目录,很麻烦,所以总结了三种在当前目录下直接打开cmd窗口的方法,供以后开发时参考,相信对其他人也有用. 方法一 在当前目录按住shift再右键. 会看到右键菜单 ...