最近工作正好有闲暇时间,根据公司安排先前期学习调研一下“微信小程序”,以供后期解决相关的运营需求,而本篇文章就是我对此次学习的一次总结。
- 什么是小程序 ?
- 如何全面具体的学习?
- 注册与新建小程序
- 认识开发工具
- 目录结构与代码构成
- JSON 配置文件
- WXML 模版文件
- WXSS 样式文件
- JS 脚本文件
- 小程序的执行流程
- 小程序知识体系导图
- 小程序开发的重要说明
- WXSS
- 模版语法
- 自定义模版
- 数据绑定
- 事件处理
- 自定义组件
- 行为 - Behaviors
- 生命周期函数
- 作用域
- 多页面数据共享
- 版本库兼容性
- 用户权限
- WXS
- 开源项目参考
- 下一步计划
什么是小程序 ?
个人认为在样式、功能、使用方式上接近传统APP并依赖于微信运行环境的 H5页面就是所谓的“微信小程序”。
微信小程序对比传统的 APP,它无需安装,在微信环境中可直接运行,并且依附于微信的生态圈,所以可以被更快速,方便,高效的推广。
如何全面具体的学习?
学习“微信小程序”,可以打开“微信公众平台·小程序”平台,里面有非常详细的讲解。
https://developers.weixin.qq.com/miniprogram/dev/
在这个页面中,你可以从“介绍”、“设计”、“开发”、“运营”、“数据”等各个方面对小程序进行一个全面整体的认知。
若你是位“开发者”,那么应该专注学习“设计”,“开发”这两个方面。在“设计”方面你将学会小程序的交互和更棒的用户体验方面。而在“开发”中你将从“简易教程”、“框架”、“组件”、“API”、“工具”等全方面学习如何开发一款小程序应用。
如果有其它疑问,也可以在 社区 中进行反馈交流。
- 设计
- 开发
- 简易教程
- 框架
- 组件
- API
- 工具
注册与新建小程序
首先,你需要有一个“微信小程序”的账号。通过下面的链接,打开“微信公众平台”,然后点击最上面的“立即注册”,接着选择“小程序”。
https://mp.weixin.qq.com/
目前小程序的开放范围主要有“个人”、“企业”、“政府”、“媒体”、“其它组织”这几个。
如果你是企业级应用,可以直接在企业的微信公众号中直接添加“微信小程序”,从而无需注册。
有了小程序账号后,就可以登录“微信公众平台”,进入“微公众信平台·小程序”后台。
在“微公众信平台·小程序”后台中我们便可以根据流程提示开始新建一个小程序项目,小程序项目新建完成后,可以通过左侧栏目中的 “设置” - “开发设置” 拿到该小程序的 “AppID”,这一步至关重要,因为我们后面通过开发者工具新建的项目就需要填入 “AppID”。
“AppID” 相当于小程序平台的一个身份证 ,后续建立小程序项目,或者腾讯云服务都会使用到它,如果没有 “appID”,也可以使用开发工具上的测试号。
认识开发工具
“微信小程序”的开发需要特定的开发工具,通过“微信开发者工具”我们可以编译、调试、预览、上传、发布小程序页面,同时还可以管理微信小程序的授权状态等。
下载 > 微信开发中工具
“微信开发者工具”分为 “beta版” 与 正式版。一般我们使用的都是正式版,而像Git
,NPM
之类新功能目前只有“beta版“才支持。
“微信开发者工具”下载安装完成后,可以选择建立“小程序项目”,然后输入小程序的名称,路径以及 “appID”,然后点击“确定”即可。
“微信开发者工具”不仅可以开发小程序项目,还可以开发“插件”、“代码片段”等。
“微信开发者工具”主要有以下几个重要功能点:
- 模拟器:可以设置网络、分辨率、缩放以及选择设备类型。
- 编辑器:与传统的编辑器相同,进行代码的编辑。
- 调试器:浏览器控制台,与Chrome基本相同主要新增了 appData、WXML、sensor等小程序专属的选项。
- 编译、预览、调试、远程调试。
- 详情:可以进行“项目设置”,“域名信息”、“腾讯云状态”。
- 其它常用功能:社区、上传、缓存管理、场景值、腾讯云(提供了一套完整的小程序解决方案,方便新手练习)。
https://developers.weixin.qq.com/miniprogram/dev/devtools/debug.html (更多开发工具的介绍)
“微信开发者工具”常用快捷键:
键名 | 说明 |
---|---|
Ctrl+B | 编译项目(焦点在开发工具中) |
Ctrl+R | 编译项目(焦点不在开发工具中) |
Ctrl+Shift+P | 预览项目 |
Shift+Alt+F | 格式化代码 |
目录结构与代码构成
下面是一个小程序完整的目录结构图 (请右击查看大图)。
通过观察上图的目录与文件,你会发现小程序的代码主要有以下几个文件类型构成:
- .json
- .WXML
- .wxss
- .js
JSON 配置文件
.json
文件是小程序的配置文件。
在小程序中配置文件按照应用范围又分为以下主要四种:
- project.config.json
- app.json
- pages.json
- component.json`
project.config.json
它是开发者工具和小程序项目的共同配置文件,它可以在多个开发者中维护统一的开发设置和开发环境。例如编辑器的颜色、ES6转ES5、上传代码时自动压缩、是否校验不合法域名、版本库等等。
当新的开发者下载了开发者工具后,只需要将团队中的 project.config.json
文件拷贝到本地小程序的根目录中即可。
https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html (更多关于project.config.json)
app.json
它是整个小程序应用的全局配置文件,可以设置小程序的页面、窗口、tab栏、网络超时、debug、插件、分包、多线程等。
其中常用到的字段是 pages
、window
以及 tabBar
。pages
用于配置小程序的页面路径,其值是一个数组,数组中的第一个元素就是小程序的主页,并且在开发工具中新增一个路径时,编辑器会自动创建对应页面的目录以及文件。
{
"pages":[
"pages/index/index",
"pages/logs/logs"
]
}
PS:路径中的文件名 "index" 与 "logs" 不要加扩展名,小程序的编译工具会自动寻找对应的文件类型进行处理。
window
用于配置窗口的样式以及标题等。
属性 | 说明 | 取值 |
---|---|---|
navigationBarBackgroundColor | 导航栏背景颜色 | HEX |
navigationBarTextStyle | black / white | |
navigationBarTitleText | 导航栏标题文字内容 | text |
backgroundColor | 窗口的背景色 | HEX |
tabBar
也是比较常用的配置,用于设置 tab栏的位置(上、下)以及按钮的文字,样式和 icon。
https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE (更多关于app.json)
pages.json
每个页面都有自己的 pages.json
文件。pages.json
文件可以在全局配置 app.json
的基础上对页面进一步的进行设置。例如导航栏的颜色,标题文字等。
另外 pages.json
还可以通过 usingComponents
字段来声明当前页面引用了那些自定义组件。
https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#%E9%A1%B5%E9%9D%A2%E9%85%8D%E7%BD%AE (更多pages.json)
componet.json
componet.json
是自定义组件的配置文件。
{
"component": true, // 自定义组件声明
"usingComponents": {} // 可选项,用于引用别的组件
}
WXML 模版文件
你可以将 WXML
等同于传统 WEB开发时用到的 html
,他们都是用来描述页面的结构骨架,不同的是 HTML文件由一个个html标记(Tag)组成,而 WXML则是有与之类似的“组件”组成。
除了在结构特性上与 HTML一致外,WXML 文件还支持特定的模版语法,数据绑定,事件处理、自定义模版等等。
同样的 WXML也可以分为页面的 WXML文件,自定义模版的 WXML文件以及自定义组件中的 WXML文件。
WXSS 样式文件
wxss
具有大部分 CSS的功能,所以你可以像 CSS一样去编写小程序的样式文件。
对于整个小程序公用的样式,可以放置在 app.wxss
文件中,而对于页面专用的样式,则写到对应页面的 pages.wxss
文件中,其次便是自定义组件也会含有自己的 component.wxss
文件。
JS 脚本文件
在小程序的脚本文件中,我们可以处理事件,响应用户请求,获取接口数据,改变数据状态...并且小程序的脚本文件默认支持commonJS
规范,可以直接通过 require()
来导入模块,module.exports
导出模块,就编码的角度而言,与我们普通编写脚本文件并没有什么太大的区别,如果非要说区别的话,就是小程序中的脚本可以调用小程序内置的一些API接口,例如授权,支付等。
同样的app.js
用于存放全局的数据和方法,而 pages.js
则存放每个页面自己的数据和方法,对于组件中的脚本文件而言,它保存的则是组件自己的数据和方法
小程序的执行流程
(请右击查看大图)
当微信客户端打开一个小程序的时候,会将整个小程序的代码包下载到本地,然后通过读取 app.json
文件获取页面的路径,并将第一条路径作为首页,并根据 app.json
中的配置来初始化小程序窗口的样式。
紧接着,微信客户端再将 app.js
装载进来,执行其中的 App()
方法,实例化一个小程序对象(整个微信小程序也只有一个这样的实例对象,并且全部页面共享该对象,你可以在每个页面使用 getApp()
方法来获取)。
当小程序实例对象创建完成后,会触发生命周期中的 onLaunch()
函数,然后继续装载小程序中的每个页面(默认便是首页),在装载页面的时候,同样的会先装载 pages.json
的代码,用来初始化页面与窗口的样式,然后再装载 WXML
文件以及其使用到的资源(wxs,模版、组件)来生成页面结构,一切就绪再加载 wxss
获取页面样式,最后再去装载 .js
的脚本文件。
当最后的 .js
文件也被装载进来后, 就会调用脚本中的Page()
构造函数,还回一个页面的实例对象,页面实例对象创建好后,就会根据其中的 data 数据与 WXML文件中的内容 一起渲染出最终的页面,最后页面渲染完成后,并且在这一过程中,页面实例会根据不同时期的状态触发不同的页面生命周期函数。
明白小程序的基本执行流程,对后面了解小程序执行的生命周期非常有帮助。
小程序知识体系导图
(请右击查看大图)
小程序开发的重要说明
小程序开发还是很简单的,像一些 API接口以及组件的使用,在开发手册上都有详细列举,所以这里我就将我个人认为小程序中比较常用或者是比较重要(跟传统web开发有点区别)的地方单独记录下来。
WXSS
WXSS
是基于 CSS 改进而来的,所以大部分的 CSS写法也可以套用在 WXSS
上,这里主要对这两者重点的区别加以说明。
rpx
新增的相对单位,rpx
默认将屏幕划分为750个单位。
注意的是:px
在小程序中依然也可以用。
选择器
WXSS 支持的选择器相比 CSS要少一些,但是主流的:类、ID、元素,分组、伪类(after,before)、伪元素(:hover 这里表示元素选中)等选择器都支持。
模块化样式
支持 @import "path"
导入样式。
内嵌样式
小程序中组件支持通过 style
属性来内嵌内联样式,并且还可以通过表达式来接收绑定的数据。
背景图
wxss 不支持本地图片(相对路径图片)作为背景图,对于需要内嵌在 wxss文件中的图片,请使用 base64
或者是网上的图片。
不过,image 组件支持本地图片
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html (更多关于WXSS)
模版语法
WXML文件也称之为“WXML模版”文件,它与 HTML文件结构相同,都是有许多结构标记组成,只是在小程序中,这些标记被称之为“组件”。
WXML文件与 HTML文件的不同在于WXML模版支持特定的模版语法,可以直接再模版中进行运算处理。
表达式
WXML支持通过 {{variant}}
表达式来获取对应页面脚本中 data
定义的数据。
#page.wxml
{{names}}
#page.js
Page({
data:{
names:"xiaoming"
}
})
{{}}
表达式不仅可以读取变量的值,还支持一些常规的运算操作,比如“算数运算”、“三元运算”、“比较运算”、“字符串运算”等,另外还可以在表达式中定义数组、对象等类型的值。
{{a + b}} + {{c}}
{{flag ? true : false}}
{{length > 5}}
{{"hellow" + name}}
{{[zero, 1, 2, 3, 4]}}
{{for: a, bar: b}} | {{...obj1, ...obj2, e: 5}} | {{name,age}}
条件判断
微信小程序支持在WXML模版文件中进行条件判断。
...
...
...
循环遍历
WXML模板同样还支持循环遍历。
{{item}} - {{index}}
其中 arrs
是页面脚本 data
中定义的一个数组,而 item
与 index
都是循环体中固定的写法,分别表示了每次循环“项”和每次循环的“索引”。
列表渲染
{{i}} * {{j}} = {{i * j}}
wx:for-item
与 wx:for-index
用来解决多层循环嵌套item
与 index
重复的问题。
另外,还有一个 wx:key
的控制属性,它的取值有 String
与 *this
两种。String
可以是 for循环中每个 item自身的 property
的名称,这个 property
的值要保证在整个循环遍历中,相对其它的 item property
的值都是唯一的。*this
则是代表每次循环的 item本身,这种表示需要 item 本身是一个唯一的字符串或者是数值。
wx:key
要求唯一的原因是当数据改变触发渲染时,列表中通过 wx:key
指定的选项,不会被重新渲染只会改变位置顺序,也就是说不会被移出重新插入,从而能够保持一种固定的状态。这样也更加的节省性能。当然如果你非常确定你的列表是静态的并且不会发生改变,那么也无需使用该属性。
block
当我们在模版中使用控制属性,总需要将其挂载到一个组件上,这往往就会让不需要组件加入到页面渲染中。
为了解决这个问题,小程序提供了另一个特殊的组件:
,使用 block
以作为控制属性的载体,并切不会被渲染到页面上。
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/ (更多关于模版以及模版语法)
自定义模版
WXML支持两种模版类型,一种是通过 组件定义的“动态模版”,我们可以向“动态模版”中传入数据,并运用表达式、模版语法、控制属性等进行运算。另一中就是“静态模版”,通过
组件将静态的 wxml 文件引入到指定的位置中。
动态模版
定义模版
调用模版
外部导入模版并调用
#引入外部模版
静态模版
总结
对比 import
,include
只是单纯的将一个模版中的所有组件内容拷贝到你使用 include
的位置处(需要注意的是模版中的 template
与 wxs
不能被拷贝)。除此之外,import
有自己的作用域,如果要传递数据到对应的 template内,须要借助 data
属性。
数据绑定
微信小程序支持类似 vue的MVVM模式,即数据(逻辑层)与视图(渲染层)相互分离,当数据发生改变的时候,可自动的刷新视图。
使用起来也非常简单,通过模版的表达式结合逻辑层的 setData
方法既可以使用。
示例:
{{names}}
Page({
data:{
names:"xiaoming"
},
onLoad:function(){
this.setData({names:"xiaohong"});
}
})
事件处理
事件绑定(支持事件冒泡)
bind:eventName
事件绑定(不支持事件冒泡)
catch:eventName
事件捕获(可以再冒泡)
capture-bind:eventName
事件捕获(不会冒泡)
capture-catch
自定义组件
“自定义组件”可以认为是具有特定可复用功能的最小型页面,“自定义组件”与小程序内置组件一样可以定制自己的功能,数据还有属性。
“自定义组件”的目录结构以及代码构成与普通页面完全一致,其中 *.js
是自定义组件的数据方法文件,*.json
是配置文件。*.wxml
是自定义组件的结构模版文件,*.wxss
是自定义组件的样式文件。
首先建立组件的目录,然后创建以下几个文件(比如这里以assambley)为例:
assembly:
- assembly.wxml
- assembly.wxss
- assembly.js
- assembly.json
接着在 assembly.wxml
、assembly.wxss
中编写好你的结构与样式代码,在你的JS文件中调用 Component()
构造函数,来实例化一个组件实例:
Component({
//行为
behaviors:[],
//数据
data: {
names: Math.random()
},
//属性
properties: {
nowIn: String
},
//方法
methods: {
showData: function(e) {
let radomNumber = Math.random();
this.setData({ names: radomNumber });
//自定义触发的事件
this.triggerEvent('assmbleySignal', this.data.names);
}
},
//生命周期函数
attached: function() {
this.triggerEvent('assmbleySignal', this.data.names);
}
});
最后在 assembly.json
中进行组件的声明。
{
"component":true
}
这样一个组件就定义完成了,使用的时候,只需要在用到的页面或者是其它组件中,对它们的配置文件添加以下配置即可(例如这里以index页面为例)
#index.json
"usingComponents": {
"assembly": "/pages/component/assembly/assembly"
}
需要注意的是,在 properties
中自定义属性的时候要用驼峰命名,但是应用在组件上的时候要记得用小写并且采用 “-” 分割,例如:
properties:{
nowIn:String
}
使用:
PS:自定义事件方法 onAssmbleySignal
在index.js中定义。
https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component (更多关于组件)
行为 - Behaviors
通过 behaviors
(行为)可以让多个组件之间的“属性”、“数据”、“方法”、“生命周期”实现共享。
并且 behavior
中还可以引用其它的 behaviors
。 属性会按照先后进行覆盖,而数据虽然也会覆盖,但是如果类型是对象则会进行合并,生命周期函数也会顺序触发,多个组件调用同一个 behaviors
则生命周期函数也只会执行一次。
module.exports = Behavior({
behaviors:[],
properties: {
behavior_attr: String
},
data: {
behavior_data: {}
},
methods: {
behavior_method: function() {
console.log('behavior_method')
}
},
attached: function() {
console.log('behavior-attached');
}
});
组件中调用:
var myBehavior = require('./behavior');
Component({
behaviors: [myBehavior],
data: {
names: Math.random()
},
properties: {
nowIn: String
},
methods: {
showData: function(e) {
console.log('component showData');
}
},
lifetimes: {
attached: function() {
console.log('component attached');
}
}
});
behaviors
除了自定义的还有内置的 behaviors
var myBehavior = require('./behavior');
Component({
behaviors: ['wx://form-field'],
data: {
names: Math.random()
},
properties: {
nowIn: String
}
});
生命周期函数
小程序中的生命周期函数主要有以下几类:
- 应用实例
- 页面实例
- 组件实例
小程序应用的生命周期
状态名 | 说明 |
---|---|
onLuanch | 小程序实例初始化 |
onShow | 小程序启动,或从后台进入前台显示 |
onHide | 小程序隐藏,或从前台进入后台 |
onError | 当小程序发生脚本错误,或者 api 调用失败时 |
onPageNotFound | 当小程序出现要打开的页面不存在的情况 |
页面的生命周期
状态名 | 说明 |
---|---|
onLoad | 页面资源加载完毕 |
onShow | 页面显示(但不代表页面已经绘制完毕) |
onReady | 页面初次渲染完成 |
onHide | 页面隐藏 |
onUnload | 页面被卸载 |
PS:需要注意的是小程序中tab切换只是多个页面的显示隐藏切换,而不会重新加载,如果使用 navigator
等跳转则每次都会重新加载,显示,渲染。
组件的生命周期
状态名 | 说明 |
---|---|
created | 创建组件实例,注意此时无法使用 this.setData 方法 |
attached | 组件实例进入页面节点树时执行 |
ready | 组件布局完成后执行,此时可以获取节点信息(使用 SelectorQuery ) |
moved | 组件实例被移动到节点树另一个位置时执行 |
detached | 组件实例被从页面节点树移除时执行 |
生命周期函数的默认流程
假设一个小程序(含有页面,组件)被打开并且正常运行,那么它一般都会经过以下生命周期的改变流程:
实际上小程序中还存在另一种生命周期:“行为 Behaviors
的生命周期,不过其常用的也就 attached
,因此可以再需要的时候自己去查阅文档。
作用域
在小程序中,JS文件,模版文件(动态模板),wxs文件都有自己的独立作用域,模块的导入导出遵循 CommonJS 规范。
多页面数据共享
如果想实现多页面数据共享或者是跨页面数据交互,可以采用以下方式:
- app.js 定义
golbalData
对象 - 利用
Storage
实现 - 利用页面传参来实现页面间的数据交互。
版本库兼容性
通过 canIUse
可以判断小程序的API,回调,参数,组件等是否在当前版本可用。
返回值一般而言都是布尔值。
wx.canIUse('openBluetoothAdapter')
wx.canIUse('getSystemInfoSync.return.screenWidth')
wx.canIUse('getSystemInfo.success.screenWidth')
wx.canIUse('showToast.object.image')
wx.canIUse('onCompassChange.callback.direction')
wx.canIUse('request.object.method.GET')
或者你也可以基于能力去判断:
if(this.setData) //....
用户权限
开发者通常向用户发起权限授权主要是通过 wx.authorize
这个接口实现,但需要注意的是如果调用的是“用户信息”,则需要使用特定的按钮组件来引导用户操作,单纯的使用 scope:scope.userinfo
是无法弹出授权弹窗。
另外,每个权限都有对应的 API接口可以获取该权限的的状态以及详情,例如:wx.getUserInfo、wx.getLocation
等..
如果想查看全部权限的状态,可以通过另一个 API接口获取当前的权限列表:wx.getSetting
。
对于用户拒绝授权的接口并且短时间无法再次打开,我们可以调用 wx.openSetting
来让用户自己手动操作。
WXS
WXS
代码可以编写在 WXML 文件中的
标签内,或者保存在以 .wxs
为后缀的文件里。WXS
可以看作成小程序自己定义的一套脚本,它的语法非常类似于原生 JS,但是运行环境并不相同,所以有些 JS的对象或方法无法使用,也不能调用小程序的内部 API,其主要目的还是为增强 WXML的模版数据处理能力。
不论是 WXML中的 wxs内的代码,还是独立的 *.wxs
文件中的代码,它们都有独立的作用域。
实例:
function methodName(value){ return value.split(','); }
module.exports = methodName; //需要导出
调用模块中的方法
//names是页面JS中的data配置的。
{{item}}
或者你可以单独将wxs中的脚本单独的保存在一个文件中,然后使用wxs引入。
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/ (更多关于WXS)
开源项目参考
https://github.com/tumobi/nideshop-mini-program (NideShop:基于Node.js+MySQL开发的开源微信小程序商城(微信小程序)
https://github.com/EastWorld/wechat-app-mall (微信小程序商城,微信小程序微店)
https://github.com/ecomfe/echarts-for-weixin (ECharts 的微信小程序版本)
https://github.com/sqaiyan/NeteaseMusicWxMiniApp (仿网易云音乐APP的微信小程序)
https://github.com/zce/weapp-demo (仿豆瓣电影微信小程序)
https://github.com/myvin/juejin (掘金小程序)
https://github.com/xiehui999/SmallAppForQQ (高仿手机QQ应用程序
https://github.com/liuxuanqiang/wechat-weapp-mall (微信小程序-移动端商城)
https://github.com/web-Marker/wechat-Development (微信小应用-小程序-demo-仿芒果TV)
https://github.com/lanshan-studio/wecqupt (We重邮 - 微信小程序 )
https://github.com/RebeccaHanjw/weapp-wechat-zhihu (微信中的知乎--微信小程序 demo)
https://github.com/eyasliu/wechat-app-music (微信小程序:音乐播放器 )
https://github.com/skyvow/m-mall (微信小程序-小商城前台(基于 WeUI.wxss、ES6 前端技术开发...)
https://github.com/sesine/wechat-weapp-movie (电影推荐 - 微信小程序)
https://github.com/ahonn/weapp-one (仿 「ONE · 一个」 的微信小程序)
https://github.com/kraaas/timer (小程序版番茄时钟)
https://github.com/hijiangtao/weapp-newsapp (微信小程序-公众号热门文章信息流)
https://github.com/zhengxiaowai/weapp-github (微信小程序--github)
https://github.com/vace/wechatapp-news-reader (微信小程序 —— 新闻阅读器)
https://github.com/natee/wxapp-2048 (微信小程序2048)
下一步计划
在掌握小程序开发的基础知识后,后面我将会多做小程序的实战项目,掌握小程序的开发框架、收集小程序常用的插件、样式UI库,以及汇总小程序开发过程的问题收获。
最后,如果文章中存在错误或者是歧义的地方,也或者您有更好的建议,请务必跟我联系或者给我留言。
感谢您的批评指正!