从零开发微信小程序
什么是微信小程序?
微信小程序是不用下载安装就可使用的,运行在微信 APP 上的应用。它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用,体现了“用完即走”的理念。小程序分为视图层和逻辑层,视图层运用了 wxml 和 wxss,有时候还会用到 wxs。逻辑层运用了 js、json。小程序跟普通的网页开发十分相似,小程序的主要开发语言是 JavaScript,wxml 的写法和 html 类似,wxss 跟 css 的也是用理。尽管两者有较大的相似性,两者还是有不小的区别。
-
线程
网页开发渲染线程和脚本线程是互斥的,当 JS 引擎线程执行时,GUI 渲染线程会被挂起;当 GUI 渲染线程执行时,JS 引擎线程会被挂起。两者无法同时执行。所以如果 js 逻辑写得过于复杂,长时间的脚本运行可能会导致页面失去响应,渲染线程被一直挂起。
小程序则不存在互斥情况,分别在渲染层(视图层)和逻辑层中有条不紊地同时执行。这意味着 在 js 阻塞期间用户依然可以做非常有限的交互,比如页面上下滚动等等,这是小程序的革新之处。
-
没有浏览器对象
小程序的逻辑层和渲染层是分开的,逻辑层运行在 JSCore 中。JavaScriptCore 是苹果 Safari 浏览器的 JavaScript 引擎,它是苹果的浏览器引擎 WebKit 中组成部分,一个完整浏览器对象还需要 WebKit 里的 webcore 把 HTML 解析成 DOM 树,因而 jscore 缺少相关的 DOM API 和 BOM API。前端开发非常熟悉的一些依赖 DOM 操作库,例如 jQuery 等,在小程序中是无法运行的。同时 JSCore 的环境同 NodeJS 环境也是不尽相同,所以一些 NPM 的包在小程序中也是无法运行的。
-
运行环境
小程序运行的环境是微信(App);普通网页的运行环境是浏览器,包括小程序里的内嵌网页 webview。小程序的运行环境是微信开发团队基于浏览器内核完全重构的一个内置解析器,针对性做了优化,配合自己定义的开发语言标准,提升了小程序的性能。
小程序初始目录
├── pages(存放页面渲染文件)
│ └── index
│ ├── index.wxml
│ ├── index.js
│ ├── index.json
│ └── index.wxss
├── utils(工具类)
├── app.js
├── app.json
├── app.wxss
└── project.config.json
-
全局配置
小程序根目录下的 app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。完整配置项说明请参考小程序全局配置。
例:
{ "pages": [ "pages/index/index", ], }
在 app.json 填写字段,配置新的渲染页面,根目录下的 pages 文件会生成 index 文件夹,里面的 wxml、wxss、js、json 用于解析生成 index 页面。
-
页面配置
每一个小程序页面也可以使用同名 .json 文件来对本页面的窗口表现进行配置。完整配置项说明请参考小程序页面配置。页面配置的优先级比全局配置要高,页面中配置项会覆盖 app.json 的 window 中相同的配置项。
比如你整个小程序的风格是蓝色调,那么你可以在 app.json 里边声明顶部颜色是蓝色即可。实际情况可能不是这样,可能你小程序里边的每个页面都有不一样的色调来区分不同功能模块,每个页面可能需要做不一样的处理,有独特的需求,所以为了方便页面配置的优先级更高。
例:
app.json:
{
"window": {
"navigationBarTitleText": "标题一"
},
}
index.json:
{
"navigationBarTitleText": "标题二",
}
index 页面导航栏的标题是标题二,因为优先级更高。如果 index.json 没有配置"navigationBarTitleText"属性,则显示标题一。
-
sitemap 配置
微信现已开放小程序内搜索,开发者可以通过 sitemap.json 配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中。
-
开发工具配置
我们在使用开发工具写代码时,通常会根据自己的偏好,配置工具的界面布局或是界面颜色等等。如果我们换了一台电脑继续开发,重新下载工具后发现又要重新配置工具,这是很麻烦的。
小程序开发者工具在每个项目的根目录都会生成一个 project.config.json,你在工具上做的任何配置都会写入到这个文件,当你重新安装工具或者换电脑工作时,你只要载入同一个项目的代码包,开发者工具就自动会帮你恢复到之前你开发项目时的个性化配置,其中会包括编辑器的颜色、代码上传时自动压缩等等一系列选项。
小程序框架
小程序框架系统分为两部分:逻辑层(App Service)和 视图层(View)。小程序框架的核心是响应的数据绑定系统。当做数据修改的时候,只需要在逻辑层修改数据,视图层就会做相应的更新。这类似于普通网页里 vue 的数据绑定,vue 使用虚拟 dom 抽象了渲染过程,使得视图层和渲染层做了解耦。统一把数据放在 data 对象里面,这样逻辑层对渲染层的描述可以是 web、native、小程序等多端的,实现了跨平台的能力。
例如:
pageA.wxml:
<view>{{message}}</view>
pageA.js:
Page({
data: {
message: Hello world!
},
})
逻辑层数据中的 message 与视图层的 message 进行了数据绑定,所以在页面一打开的时候会显示 Hello world!
-
逻辑层(App Service)
小程序开发框架的逻辑层使用 JavaScript 引擎为小程序提供开发者 JavaScript 代码的运行环境以及微信小程序的特有功能。逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。开发者写的所有代码最终将会打包成一份 JavaScript 文件,并在小程序启动的时候运行,直到小程序销毁。这一行为类似 ServiceWorker,所以逻辑层也称之为 App Service。
-
页面生命周期函数
Page({ onLoad: function(options) { // 页面创建时执行 }, onShow: function() { // 页面出现在前台时执行 }, onReady: function() { // 页面首次渲染完毕时执行 }, onHide: function() { // 页面从前台变为后台时执行 }, onUnload: function() { // 页面销毁时执行 }, onPullDownRefresh: function() { // 触发下拉刷新时执行 }, onReachBottom: function() { // 页面触底时执行 }, onShareAppMessage: function () { // 页面被用户分享时执行 }, onPageScroll: function() { // 页面滚动时执行 }, onResize: function() { // 页面尺寸变化时执行 }, })
-
setData
使用 setData 来改变 data 值
pageA.wxml:
<view>{{message}}</view>
pageA.js:
Page({ data: { message: Hello world! }, onLoad: function(options) { // 页面创建时执行 this.setData({ message: "Hello!" }) }, })
最终显示 Hello!
-
-
视图层(View)
框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。
将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。
WXML(WeiXin Markup language) 用于描述页面的结构。
WXS(WeiXin Script) 是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
WXSS(WeiXin Style Sheet) 用于描述页面的样式。
组件(Component)是视图的基本组成单元。-
WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
数据绑定:
pageA.wxml:
<view>{{message}}</view>
pageA.js:
Page({ data: { message: Hello world! }, })
列表渲染:
pageA.wxml:
<view wx:for="{{array}}" wx:for-item="item1">{{item1}}</view>
pageA.js:
Page({ data: { array: [孙悟空, 猪八戒, 沙和尚, 唐僧] } })
用 wx:for 进行遍历渲染,遍历的次数为数组 array 下标的个数,item1 是数组的元素,上面进行循环渲染后,相当于:
<view>孙悟空</view> <view>猪八戒</view> <view>沙和尚</view> <view>唐僧</view>
编译器显示结果:
孙悟空 猪八戒 沙和尚 唐僧
条件渲染:
pageA.wxml:
<view wx:if="{{show0}}">班级</view> <view wx:if="{{show1}}">姓名</view> <view wx:if="{{str == 'hello'}}">学号</view>
pageA.js:
Page({ data: { show0: true, show1: false, str: "hello", } })
用 wx:if 进行条件渲染,当数据里的布尔值为 true 时,则正常渲染,若为 false 则不渲染。上面进行循环渲染后,相当于:
<view>班级</view> <view>学号</view>
编译器显示结果:
班级 学号
-
WXSS
WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。WXSS 用来决定 WXML 的组件应该怎么显示。WXSS 具有 CSS 大部分特性。同时 WXSS 对 CSS 进行了扩充以及修改。与 CSS 相比,WXSS 扩展的特性有:尺寸单位、样式导入。
class 与 id 选择器:
pageA.wxml:
<view class="label">Hello world!</view> <view id="btn">click!</view>
pageA.wxss:
.label { color: red; } #btn { color: blue; }
在 wxss 使用英文句号".“进行类选择,”#"进行 id 选择,最终 Hello world!字体为红色,click!字体为蓝色。
目前 wxss 支持的 css 选择器有.class、#id、element、element, element、::after、::before
全局样式 app.wxss:
app.wxss 会作用于全部页面,页面的局部样式会优先于全局样式
pageA.wxml:
<view class="label">Hello world!</view> <view class="btn">click!</view>
pageA.wxss:
.label { color: green; }
app.wxss:
.label { color: red; } .btn { color: yellow; }
最终 Hello world!字体为绿色,click!字体为黄色。
尺寸单位:
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为 750rpx。如在 iPhone6 上,屏幕宽度为 375px,共有 750 个物理像素,则 750rpx = 375px = 750 物理像素,1rpx = 0.5px = 1 物理像素。
.label { color: red; font-size: 20rpx; }
如果是 iPhone6,屏宽 375px, 则 1rpx = 0.5px,所以 20rpx = 10px。因为 iPhone6 的换算简单,所以一般我们在编译器使用 iPhone6 进行开发。
-
WXS
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。由于小程序的视图层和逻辑层的线程是分开运行的,虽然可能不会发生 js 阻塞,但是两个线程之间的交互成本较高,使用 setData 改变 page 里的 data 值非常消耗性能。如果频繁地使用 setData(比如我们需要写 js 动画,动画要求有 60 帧才顺滑,则我们需要一秒钟改变 60 次 data 的值),小程序的视图层将会明显地出现卡顿现象。wxs 在视图层,与需要渲染的 wxml 在同一线程里面,所以在需要频繁做数据处理时,我们会优先使用 wxs。
-