一、简介
微信小程序是一种区别于native App和网页应用的一种应用形态。在很多场景下我们会选择微信小程序来实现我们的应用。
从很多角度看,小程序和网页应用都有很大相似性,比如小程序和网页应用都可以运行在微信客户端,都可以进行常见的交互,都是使用js实现。
但是小程序和网页有很大区别:
从用户角度
- 体验更好一些
- 不是通过url访问,而是内置于微信的生态中,通过搜索、访问过的记录、二维码、公众号关联。
- 小程序工具属性更强,而网页内容属性更强
从开发者角度,小程序和网页也有很大区别
- 开发语言:虽然都是用js,模板语法和样式语法也很类似,但是微信小程序内置框架语法,不能像开发网页应用时候可以选择Vue、React等框架。微信小程序框架语法无法选择。由于运行环境不同,小程序里面不能使用浏览器提供的dom、bom等环境相关的API。
- 调试:小程序必须要在微信开发者工具中调试。
- 发布:网页开发后通过各种方式发布到服务器,而微信小程序开发完成后要在微信开发者工具中提交到微信后台,在小程序后台可以进行管理。
- 能力增强:微信小程序提供了比网页更强大的能力,并且提供了很多开放能力,可以获取用户信息、电话,可以音视频通信,可以对接广告等等。
学习微信小程序,我们需要先了解微信的生态,包括公众平台、开放平台、公众号、订阅号、服务号、小程序、小游戏等。
还要学习小程序从注册到开发、后台管理小程序、开发、调试、发布完整流程。
微信小程序是属于微信公众平台的的一种账号类型,除了微信小程序,微信公众平台的账号还有订阅号和服务号,订阅号和服务号统称为微信公众号,它们的作用是给媒体提供新的信息传播方式和给企业提供业务服务能力和用户管理能力。而微信小程序则作为有出色的应用体验的载体,承载工具类产品。
除了微信公众平台,还有微信开放平台来提供基于微信用户体系的一些能力。
那么微信公众平台和开放平台有什么区别呢?
公众平台vs开放平台
一句话回答:
微信公众平台是给编辑的,微信开放平台是给技术的。
>
微信公众平台能干什么?
• 写文章发文章
• 和粉丝聊天
• 配置菜单
• 开通各种公众号的权限(仅限自己的公众号)
• 启用开发者模式,开发自己的公众号
• 投放广告
• 查看数据
>
微信开放平台能干什么?
• APP想用微信登录/分享到朋友圈等
• PC网站想用微信登录等
• 注册公众号第三方平台(服务所有公众号)
• 注册小程序第三方平台(提供小程序模板)
• 绑定公众号或小程序,以形成UnionID
注册
微信公众平台包括公众号和小程序,其中公众号又包括订阅号、服务号。注册时候需要邮箱和主体。
个人作为主体,主体信息包括身份证号、手机号等;企业作为主体,主体信息包括营业执照号、法人等。
一个主体可以注册的公众号和小程序是有限的,目前主体分为个人主体和企业主体,个人主体最多能注册一个公众号、5个小程序,企业、个体工商户、其他组织可以注册2个公众号、50个小程序,政府、媒体可以注册50个公众号、50个小程序。
在注册微信公众平台账号时候,邮箱是必需信息,邮箱在个人微信号、公众平台、开放平台是唯一的。
注册好后将成为该小程序号的管理员,该小程序还可以可以添加成员,成员有不同角色,不同角色有不同的权限,角色包括运营者、开发者、数据分析者、体验成员。
注册好后,我们可以在小程序后台管理小程序。后台可以管理小程序的版本、成员、开发等等。
底层技术
小程序的宿主环境和网页不同
小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。
逻辑层用JsCore实现,渲染层用webview实现。
二、开发
由于微信小程序运行环境和发布部署过程都和网页应用开发不同,因此需要一个专门的工具提供支持。微信官方提供了微信开发者工具,微信开发者工具可以认为是微信小程序的IDE,提供了开发、调试、发布、版本管理等一系列方便的功能辅助开发微信小程序。微信开发者工具除了支持微信小程序的开发流程,还支持微信网页应用开发,但这里我们主要关注如何使用微信开发者工具开发微信小程序。
开发者工具
通常我们使用微信官方提供的开发者工具进行开发,微信开发者工具可以进行公众号网页和小程序开发。
使用微信开发者工具可以方便地进行调试和发布。
使用微信开发者工具时候需要使用小程序的管理员或者开发者的微信号登录,因为调试、上传等操作需要验证身份和权限。
微信开发者工具从界面上看主要有几个模块,模拟器、编辑器、调试器,还有工具栏。
- 模拟器
用于运行小程序,方便调试。
- 编辑器
用于编辑代码,通常我们不使用这个编辑器,而是用自己习惯的编辑器。编辑完代码后,模拟器上的小程序会更新。
- 调试器
非常类似Chrome的开发者工具,提供控制台、元素查看器、网络查看器等有用的调试工具。
- 工具栏
工具栏中的主要操作包括
- **编译**
手动编译项目并reload调试器
预览,生成二维码,用手机扫描二维码可以查看,预览只有管理员和开发者有权限,而且有时效
真机调试也是有管理员和开发者有权限,真机调试会生成一个二维码,扫描二维码可以在手机上查看小程序效果,并且可以在电脑端调试。
- **详情**
设置一些基本信息,常用的设置有项目名称、appID(设置APpID即设置该本地小程序项目绑定的账号,上传代码时候将会上传到绑定的账号)、设置编译和调试时候的选项(例如ES6转ES5、是否校验域名合法性等)
- **版本管理**
通常我们使用git进行代码版本管理,不使用微信开发者工具提供的版本管理功能
- **上传**
将代码上传到服务器。当代码开发调试完成,就可以发布了,首先使用上传功能将代码上传到服务器,可以在后台管理中看到上传的代码。
微信小程序分为3个版本,“开发版本”、“审核版本”、“线上版本”。
刚上传完成后在“开发版本”中。刚上传成功的版本是“开发版本”,开发版本只保留每人最新的一份上传的代码,可以选择某个开发版本为“体验版本”,选为体验版本后,会生成体验版二维码。体验版只有管理员和体验成员可以访问,体验成员在后台的“管理”->“成员管理”中添加和删除。
“开发版本”已经达到上线标准后,可以提交审核,变成“审核版本”,审核通过后,就成为“线上版本”,就可以让用户正常访问了。
测试号
正式的小程序号申请需要一些资质,而且有些小程序接口是需要资质的。为了让开发者能够更方便地开发、学习、体验小程序的各种能力,微信小程序支持申请测试号,在测试号中可以进行小程序创建和、预览等。
测试号申请使用微信测试号使用微信号申请,每个微信号只支持申请一个小程序测试号。小程序测试号的管理后台只有最简单的功能,不支持上传代码、管理成员等。
申请完测试号,在微信开发者工具中配置测试号的APPID,就可以进行小程序的开发和调试了。
应用开发
小程序的运行环境和网页不同,因此当我们学习一个前端开发框架,如vue、react时候,只要学习框架的API,和如何使用框架组织我们的应用代码即可。但是学习小程序除了框架,还要学习网络请求、本地缓存、内置组件、事件系统等等和运行环境相关的API。
开发微信小程序,使用微信开发者工具先创建一个项目,创建小程序项目。创建你的第一个小程序
学习小程序一定要按照官方文档先把这个简单例子跑起来。
基本项目结构
文件类型
微信小程序包括4种文件
- .json
- .js
- .wxml
- .wxss
.js文件负责逻辑实现,.wxml负责页面结构,类似html,.wxss负责样式,.json文件负责配置。
抽象结构
从抽象角度,一个微信小程序包括应用、页面、组件。这和web开发不太一样,React框架是一切皆组件。
配置主要包括全局配置(app.json)、页面配置(微信小程序原生支持多页面)、组件配置。不同的配置会在后面相应部分介绍。
小程序的入口是app.js、app.json和app.wxss,app指应用,每个应用会有多个页面,页面的配置在app.json中tabBar字段配置底部导航栏,如果需要自定义导航栏,需要配置custom为true,关于自定义导航栏的方法后面会详细说明。
微信客户端运行小程序时候会读取app.json,解析小程序中的页面。在app.js中通过App方法注册应用。App方法传的对象参数中主要包含一些应用的生命周期。
整个小程序只有一个 App 实例,是全部页面共享的。开发者可以通过 getApp 方法获取到全局唯一的 App 实例,获取App上的数据或调用开发者注册在 App 上的函数。
创建页面通过Page方法,在Page函数传的对象参数中主要包含data、页面生命周期回调、页面事件回调。
一个页面的代码在一个目录中,包括同名的.js、.wxml、.wxss、.json文件。
在page的配置文件中,最常见的是页面引用的组件,背景颜色。
创建组件用Component方法,通过在App.json中配置”usingComponents”字段进行全局注册,全局注册之后,页面或者其他组件可以直接使用该组件。局部注册则是需要在page或者component的.json文件中进行配置”usingComponent”字段。
一个组件的代码在一个目录中,包括同名的.js、.wxml、.wxss、.json文件。
在组件的json文件中需要配置”component”: true
{
"component": true,
}
Component方法接收的对象参数主要字段有
- data // 组件中的数据
- properties // 父组件给子组件传递的属性
- observers // 监听data和properties的变化,类似vue的watch
- methods // 定义的方法,用于绑定页面事件回调
- lifetimes // 生命周期方法
更多字段见文档
https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html
可以使用ES6开发,编译时候,开发者工具会转成ES5。
模块化
小程序的模块化遵循commonJS模块规范
module.exports导出模块
require引入模块
// common.js
function sayHello(name) {
console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
console.log(`Goodbye ${name} !`)
}
module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye
var common = require('common.js')
Page({
helloMINA: function() {
common.sayHello('MINA')
},
goodbyeMINA: function() {
common.sayGoodbye('MINA')
}
})
框架
微信小程序的模板语法和vue框架有些相似的地方,比如双大括号”{{}}”插值、通过指令控制模板渲染,但是也有很多不同的地方。
模板插值
插值语法是,双大括号内是js表达式,外面是字符串。
// 数据绑定
<view> {{ message }} </view>
Page({
data: {
message: 'Hello MINA!'
}
})
// 组件属性
<view id="item-{{id}}"> </view>
Page({
data: {
id: 0
}
})
条件渲染
通过wx:if指令控制模板渲染
<view wx:if="{{condition}}"> </view>
Page({
data: {
condition: true
}
})
列表渲染
列表渲染通过wx:for实现,这个语法和vue有所不同。wx:for通过一个双大括号指定一个数组来进行循环渲染,默认前项的下标变量名默认为index,数组当前项的变量名默认为item。也可以自定义下标和当前数组元素变量名。
注意还需要wx:key为列表中唯一值。
官方文档有详细说明:微信小程序列表渲染
事件绑定
微信小程序的事件通过
事件以bind开头,或者bind:开头,如bindtap、bind:tap。取值是字符串,小程序会到页面或者组件中根据事件指定的字符串查找对应的方法。
双向绑定
双向绑定的语法是”model:”
父子组件通信
和一些web应用开发框架类似,微信小程序的父子组件通信有3中方式
1. 父组件给子组件传递属性:父组件在子组件的模板标签上传递,子组件通过properties属性接收,注意通常标签上面一般习惯是横杠连接的语法,组件接收时候会被转成驼峰格式。 [父组件给子组件传递属性](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html)
// 父组件模板
<view class="parent">
<Child user-id="{{id}}" user-name="{{name}}" />
</view>
// 父组件js
Component({
data: {
id: 12121,
name: 'Bob'
}
});
// 子组件模板
<view class="child">
userId:{{userId}}
userName: {{userName}}
</view>
// 子组件js
Component({
properties: {
userId: Number, // 变量类型
// 也可以定义成对象,更详细配置
userName: {
type: String, // 变量类型
value: '张三', // 默认值
}
}
});
2. 事件
父组件绑定事件,子组件使用this.triggerEvent(‘myevent’, myEventDetail, myEventOption)触发,父组件绑定的事件回调中使用e.detail访问子组件触发事件时候传递的参数。
内置组件
微信小程序有很多内置组件,有些起到和网页中的html的元素类似效果(像image、button等),有些提供了更强的能力(picker、live-player、scroll-view等)。
路由
路由通过app.json中的pages字段进行配置。
切换页面使用
wx.navigateTo({url: 'page/user/profile'});
方法,注意url不能是tab导航页。切换路由时候可以传递参数,类似url的query string,
wx.navigateTo({url: 'page/user/profile?userid=12321'});
传递的参数在跳转到的页面的onLoad方法中获取,微信小程序会将query string解析为对象形式,传递给onLoad
// page/user/profile
Page({
onLoad: function(options) {
this.setData({
// 12321
userid: options.userid
})
}
})
tabbar
切换导航栏和切换页面不同,切换导航栏需要使用wx.switchTab({url: '/target/path'})方法。
自定义导航栏:
- app.json的tab”custom”字段并设置为true,”list”字段配置导航的页面。
- 根目录创建custom-tab-bar目录,其中创建index.js、index.wxml、index.wxss、index.json文件,实现底部的导航栏组件。
- 在切换了页面后,需要让tabbar改变样式,高亮当前的页面tab,这个如何实现呢?每个配置了的导航的页面实例上增加了getTabBar方法,返回tabbar实例,在tabbar组件method中实现一个方法设置高亮的tab(比如switchTab),然后在每个页面onShow的回调中调用这个方法来更新tab样式。
// app.json
{
......
"tabBar": {
"custom": true,
"list": [
{
"pagePath": "pages/home/home",
"text": "首页"
},
{
"pagePath": "pages/display/display",
"text": "发现"
},
{
"pagePath": "pages/userCenter/userCenter",
"text": "我的"
}
]
}
......
}
// custom-tab-bar/index.wxml
<view
class="my-tab-bar"
>
<view class="tab-item {{currentTab === 0 ? 'active' : ''}}" bindtap="onTabTap" data-index="0">
首页
</view>
<view class="tab-item {{currentTab === 1 ? 'active' : ''}}" bindtap="onTabTap" data-index="1">
发现
</view>
<view class="tab-item {{currentTab === 2 ? 'active' : ''}}" bindtap="onTabTap" data-index="2">
我的
</view>
</view>
// custom-tab-bar/index.js
Component({
data: {
currentTab: 0
},
methods: {
switchTab(index) {
this.setData({currentTab: index});
},
onTabTap(e) {
const {index} = e.target.dataset;
const url = [
'/pages/home/home',
'/pages/display/display',
'/pages/userCenter/userCenter'
][index];
wx.switchTab({url});
}
}
});
// pages/home/home.js
Page({
onShow() {
// 让自定义tabbar修改高亮样式
this.getTabBar().switchTab(0);
},
});
本地缓存
本地缓存的使用类似网页中的localStorage。
// 获取缓存中的值
wx.getStorageSync('sessionId');
// 设置本地缓存值
wx.setStorageSync('sessionId', 'alksdjla123');
字体图标
微信小程序中不支持ttf、svg、woff、eot等字体文件,因此要把字体文件的内容转成base64放到微信小程序可以识别的wxss文件中。然后其他页面或者组件使用字体图标时候,引用字体图标的wxss文件即可。
具体做法是,生成字体图标后,将.ttf文件转为base64,放到@font-face.src中。
常用的开放能力
登录
wx.login,静默登录,不需要用户手动授权,接口可以获取授权code,使用该code可以从后端换取 openid、unionid、session_key。
需要说明的是,一个应用的登录的概念和wx.login登录并不同,有些场景登录意味着需要调用wx.login获取用户的微信账号openid或者unionid即可,有些则要获取用户详细信息,还有的可能需要获取用户电话号码。一般情况应用需要结合微信小程序提供的开发能力定制自己的登录注册逻辑,将微信用户体系和应用自身的用户体系绑定。
下面是一个示例的登录注册流程图。
获取用户信息
使用wx.getUserProfile可以在success回调中获取用户信息。包括昵称、头像、性别、地理位置。需要用户手动确认。
wx.getUserProfile接口用于替换wx.getUserInfo。新版本的微信小程序推荐使用wx.getUserProfile接口。
获取电话
使用,需要用户手动确认。
转发
使用,并且在相应页面方法并返回分享标题、分享图片、分享页面信息。
插件
插件,是可被添加到小程序内直接使用的功能组件。开发者可以像开发小程序一样开发一个插件,供其他小程序使用。同时,小程序开发者可直接在小程序内使用插件,无需重复开发,为用户提供更丰富的服务。
跨端开发框架
uni-app
uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。
taro
Taro 是一个开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信 / 京东 / 百度 / 支付宝 / 字节跳动 / QQ 小程序 / H5 / RN 等应用