小程序

小程序

简介

何为小程序

  1. 在用户的角度上,就是便捷的跟用户连接的方式。
  2. 在技术的角度上,就是在微信巨人的肩膀上快速便捷的开发程序。

小程序的组成

  1. JSON配置
  2. WXML模板
  3. WXSS样式
  4. JS脚本

JSON配置(以.json结尾的文件)

1. 作用

JSON其实我们都很了解,就是一种数据格式。那么它在小程序充当的角色就是配置的作用。比如app.json,可以进行页面注册的配置。

2. 语法

跟JS对象表达式很相像,但是有一些差别

  1. key值必须用双引号包裹起来,并且不能用单引号
  2. 数字,包括浮点数和整数
  3. 字符串,需要包裹在双引号中
  4. bool值,true或者false
  5. 数组,需要包裹在方括号中
  6. 对象,需要包裹在大括号中
  7. NULL
  8. 其他格式都会报undefined
  9. 不能添加注释

WXML模板(以.wxml结尾的文件)

WXML可以类比HTML,语法上很多相似的地方。

1. 语法
  1. 注释

    <!-- 注释 --> 
  2. 基本语法

    <标签名 属性名1="属性值1" 属性名2="属性值2" ...> ...</标签名>
  1. 严格闭合
  1. 大小写敏感
2.数据绑定

web开发是使用JS通过DOM接口进行动态的渲染页面,小程序使用数据绑定进行动态渲染。

1.基本语法:

通过{{变量名}}的形式进行动态的绑定

//WXML模板
<view>{{time}}</view>
//JS
Page({
 data: {
 time: (new.Date()).toString()
 },
 })

2. 属性也可以进行动态绑定,但是需要包括在双引号内

//WXML模板
<view height="{{height}}">{{time}}</view>
//JS
Page({
 data: {
 height: 1
 },
 })

3. 除了动态绑定,也可以在该语法下绑定常量

//WXML模板
<view >{{1,2,3}}</view>
  1. 变量名对大小写敏感
  1. 没有定义的变量或者设置为undefined的变量不会同步到WXML模板。
3.逻辑语法

1. 三元运算

//WXML模板
<view >{{a === 10 ? "a等于10的要执行的语句" : "a不等于10的要执行的语句"}}</view>

2. 字符串拼接

{{
 name: world
 }}
//WXML模板
<view >{{"hello" + name}}</view>
输出hello world

3. 算术运算

{
 a:10,
 b:2,
 c:5,
 d:2
}
<view >{{a + b}} + {{c}} + d</view>
输出:12 + 5 + d

4. 条件逻辑

if else,例子如下:

<view wx:if="{{length > 5}}" >6</view>
<view wx:elif="{{length < 2}}" >1</view>
<view wx:else>3</view>

如果需要对多个标签进行判断,则使用<block></block>

<block wx:if="{{true}}">
<view>1</view>
<view>2</view>
</block>
4.列表渲染

1. 默认

for循环,默认下标的变量名是index,默认当前项变量名为item,下标是从1开始

<view wx:for="{{array}}">
{{index}}: {{item.messge}}
</view>
Page({
 data: {
 array: [{
 message: 'foo',
 }, {
 message: 'bar'
 }]
 }
})
输出:
0:foo
1:bar

2.自定义

可以自定义下标和当前项的变量名

<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
 {{idx}}: {{itemName.message}}
</view>

3.块

<block wx:for="{{[1, 2, 3]}}">
 <view> {{index}}: </view>
 <view> {{item}} </view>
</block>

WXSS样式

1. 文件组成

  1. app.wxss是项目公共样式
  2. 页面样式是跟WXML模板同级的WXSS样式

2. 尺寸单位

我们以前描述图片一般都是使用像素px。但是现在很多类型的手机的屏幕有很多种,所以小程序使用rpx相对的单位来进行描述。

小程序进行编译之后,会对xpr进行换算,这样就能够相对屏幕,不会太多空白。以375物理像素为基准,也就是在一个宽度为375物理像素的屏幕下,1rpx = 1px。举个例子:iPhone6屏幕宽度为375px,共750个物理像素,那么1rpx = 375 / 750 px = 0.5px。

样式使用方式

  1. 引用样式

    @import './test_0.wxss'
  2. 内联样式

    <view style="color: red; font-size: 48rpx"></view>

选择器

类型选择器样例样例描述
类选择器.class.intro选择所有拥有 class="intro" 的组件
id选择器#id#firstname选择拥有 id="firstname" 的组件
元素选择器elementview checkbox选择所有文档的 view 组件和所有的 checkbox 组件
伪元素选择器::afterview::after在 view 组件后边插入内容
伪元素选择器::beforeview::before在 view 组件前边插入内容

权重

view{ // 权重为 1
 color: blue
}
.ele{ // 权重为 10
 color: red
}
#ele{ // 权重为 100
 color: pink
}
view#ele{ // 权重为 1 + 100 = 101,优先级最高,元素颜色为orange
 color: orange
}
view.ele{ // 权重为 1 + 10 = 11
 color: green
}

官方样式库

https://github.com/Tencent/we...

JS脚本

ECMAScript

小程序的JS是由ECMAScript和小程序框架和小程序API来实现.

小程序执行环境

不同手机的平台不同,ECMAScript标准不同,小程序开发工具做了一个功能可以方便去控制,不需要程序员做考虑。

开发者需要在项目设置中,勾选 ES6 转 ES5 开启此功能。

作用域

文件声明的变量和方法只在该文件下有用

当需要使用全局变量的时候getApp()获取全局实例,

// a.js
// 获取全局变量
var global = getApp()
global.globalValue = 'globalValue'
// b.js
// 访问全局变量
var global = getApp()
console.log(global.globalValue) // 输出 globalValue

如果要将这个全局变量全部可以使用在App()中进行设置

// app.js
App({
 globalData: 1
})

模块化

web开发的变量是可以被后续加载的脚本访问或者改写的,但是我们明白了上一节的作用域之后,在小程序是做不到这样的,那么如果我们需要用其他文件的方法怎么使用?

小程序将每一个JS文件作为一个模块,通过module.exports 或者 exports 对外暴露接口。

// moduleA.js
module.exports = function( value ){
 return value * 2;
}
// B.js
// 在B.js中引用模块A
var multiplyBy2 = require('./moduleA')
var result = multiplyBy2(4)

脚本的执行顺序

  1. 按照加载的模块的顺序
  2. 小程序会按照开发者在 app.json 中定义的 pages 的顺序,逐一执行。

小程序宿主环境

上一节我们明白了小程序是由JSON,WXML,WXSS,JS等文件组成,那么这些文件是怎么进行交互的,怎么协同工作的?我们现在就需要去了解小程序的宿主环境。宿主环境会提供给我们微信客户端的能力。

宿主环境

分类

宿主环境分为逻辑层和渲染层

  1. 逻辑层。JS文件运行在逻辑层。
  2. 渲染层。WXML模板和WXSS样式运行渲染层。

如何渲染

  1. 渲染层使用{{}}语法绑定变量
  2. 逻辑层负责产生,处理数据。
  3. 逻辑层通过Page实例的setData方法传递数据给渲染层。

通讯模型

渲染层和逻辑层分别由两个线程管理。渲染层使用WebView进行渲染,逻辑层使用 JsCode线程进行渲染。一个程序有多个页面,所以会有多个线程,WebView和JsCode线程最终通过微信客户端进行中转。

数据驱动

我们一开始了解的如何渲染只是一个初步了解,那么里面到底是怎么运作的呢?我们知道数据和试图应该联动变化。所以小程序就有一种方法,可以实现数据变化试图也随之变化的技术,叫数据驱动。

WXML模板可以等价于一个DOM树,通过JS也可以表示DOM树。例子如下:

//WXML模板
<view>
 <view>a</view>
 <view>b</view>
 <view>c</view>
</view>
//JS
{
 name: "view",
 children:[
 {name:"view", children:[{text:"a"}]},
 {name:"view", children:[{text:"b"}]},
 {name:"view", children:[{text:"c"}]},
 ]
}

数据驱动就是先将WXML模板转换为JS对象,然后使用Page的setData方法,给对象赋值,然后将JS对象渲染为WXML模板。过程如下:

//WXML模板
<view>{{msg}}</view>
//JS对象
Page({
 data: {
 msg: "hello world!"
 }
})

转换WXML模板为下面的JS对象

{
 name:"view",
 children: [{text: msg}]
}

使用Page实例的setData方法将msg替换为JS对象的值。

{
 name:"view",
 children: [{text: "hello world"}]
}

最终将JS对象转换为WXML模板

<view>hello world</view>
程序与页面

程序

1. 程序构造器
1. 宿主环境提供一个App()构造器来注册一个App.
2. 构造器接受一个Object参数,参数说明如表1.1,其中构造器的回调函数:onLaunch / onShow / onHide /onError
3. 这个App是单例的。
4. 构造器App()必须放在根目录的app.js里面。
5. 在其他js脚本可以通过getApp()来获取程序实例。
//app.js
App({
 onLaunch: function(options) {},
 onShow: function(options) {},
 onHide: function() {},
 onError: function(msg) {},
 globalData: 'I am global data'
})
// other.js
var appInstance = getApp()

表1.1

参数属性类型描述
onLaunchFunction当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
onShowFunction当小程序启动,或从后台进入前台显示,会触发onShow
onHideFunction当小程序从前台进入后台,会触发 onHide
onErrorFunction当小程序发生脚本错误,或者 API 调用失败时,会触发 onError 并带上错误信息
其他字段任意可以添加任意的函数或数据到 Object 参数中,在App实例回调用 this 可以访问
2. 程序的生命周期和打开场景

生命周期

  1. 初次进入小程序,微信客户端初始化好宿主环境,同时从网络下载或者从本地缓存拿到小程序的代码包,把它注入到宿主环境,初始化完毕,微信客户端就会给App实例派发onLauch事件,App构造器参数定义的onLaunch方法会被调用
  2. 进入小程序之后,用户可以点击右上角的关闭,或者按手机设备的Home键离开小程序,此时小程序并没有被直接销毁,我们把这种情况称为“小程序进入后台状态”,App构造器参数所定义的onHide方法会被调用。
  3. 当再次回到微信或者再次打开小程序时,微信客户端会把“后台”的小程序唤醒,我们把这种情况称为“小程序进入前台状态”,App构造器参数所定义的onShow方法会被调用。
特点:这些回调函数都是微信客户端根据用户操作主动触发的,为了避免程序上的混乱,我们不应该从其他代码主动调用App实例的生命周期函数。

打开场景

从群聊会话里打开,从小程序列表中打开,通过微信扫一扫二维码打开,从另外一个小程序打开当前小程序等

针对不同途径的打开方式,小程序有时需要做不同的业务处理,所以微信客户端会把打开方式带给onLaunch和onShow的调用参数options

字段类型描述
pathString打开小程序的页面路径
queryObject打开小程序的页面参数query
sceneNumber打开小程序的场景值,详细场景值请参考小程序官方文档
shareTicketStringshareTicket,详见小程序官方文档

referrerInfo Object 当场景为由从另一个小程序或公众号或App打开时,返回此字段
referrerInfo.appId String 来源小程序或公众号或App的 appId,详见下方说明
referrerInfo.extraData Object 来源小程序传过来的数据,scene=1037或1038时支持

页面

1.文件构成和路径
  1. 页面,逻辑,配置。页面由WXML模板和WXSS样式描述,逻辑由JS文件描述,配置由JSON文件描述。
  2. 一个页面的文件需要放置在同一个目录下,其中WXML文件和JS文件是必须存在的,JSON和WXSS文件是可选的。
  3. 页面路径需要在小程序代码根目录app.json中的pages字段声明,否则这个页面不会被注册到宿主环境中。例如两个页面的文件的相对路径分别为 pages/index/page. 和 pages/other/other.
2.页面构造器Page()
  1. 宿主环境提供了 Page() 构造器用来注册一个小程序页面
  2. Page()在页面脚本page.js中调用
  3. Page构造器接受一个Object参数,大致参数如下;
参数属性类型描述
dataObject页面的初始数据
onLoadFunction生命周期函数--监听页面加载,触发时机早于onShow和onReady
onReadyFunction生命周期函数--监听页面初次渲染完成
onShowFunction生命周期函数--监听页面显示,触发事件早于onReady
onHideFunction生命周期函数--监听页面隐藏
onUnloadFunction生命周期函数--监听页面卸载
onPullDownRefreshFunction页面相关事件处理函数--监听用户下拉动作
onReachBottomFunction页面上拉触底事件的处理函数
onShareAppMessageFunction用户点击右上角转发
onPageScrollFunction页面滚动触发事件的处理函数
其他Any可以添加任意的函数或数据,在Page实例的其他函数中用 this 可以访问
3. 页面的生命周期和打开参数
  1. 页面初次加载的时候,微信客户端就会给Page实例派发onLoad事件,Page构造器参数所定义的onLoad方法会被调用,onLoad在页面没被销毁之前只会触发1次
  2. 页面显示之后,Page构造器参数所定义的onShow方法会被调用,一般从别的页面返回到当前页面时,当前页的onShow方法都会被调用。
  3. 在页面初次渲染完成时,Page构造器参数所定义的onReady方法会被调用,onReady在页面没被销毁前只会触发1次,onReady触发时,表示页面已经准备妥当,在逻辑层就可以和视图层进行交互了。以上三个事件触发的时机是onLoad早于 onShow,onShow早于onReady。
  4. 页面不可见时,Page构造器参数所定义的onHide方法会被调用,这种情况会在使用wx.navigateTo切换到其他页面、底部tab切换时触发。
  5. 当前页面使用wx.redirectTo或wx.navigateBack返回到其他页时,当前页面会被微信客户端销毁回收,此时Page构造器参数所定义的onUnload方法会被调用。
4.页面数据

上一节我们知道Page构造器有一个data参数,这个参数用来初始化页面需要的数据,那么我们怎么动态的改变数据呢?使用this.setData的方法进行动态的改变数据。

// page.js
Page({
 onLoad: function(){
 this.setData({
 text: 'change data'
 }, function(){
 // 在这次setData对界面渲染完毕后触发
 })
 }
})

此外需要注意以下3点:

  1. 直接修改 Page实例的this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
  1. 由于setData是需要两个线程的一些通信消耗,为了提高性能,每次设置的数据不应超过1024kB。
  2. 不要把data中的任意一项的value设为undefined,否则可能会有引起一些不可预料的bug。
5.页面的用户行为

小程序宿主环境提供了四个和页面相关的用户行为回调:

1.下拉刷新 onPullDownRefresh

监听用户下拉刷新事件,需要在app.json的window选项中或页面配置page.json中设置enablePullDownRefresh为true。当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。

2.上拉触底 onReachBottom

监听用户上拉触底事件。可以在app.json的window选项中或页面配置page.json中设置触发距离onReachBottomDistance。在触发距离内滑动期间,本事件只会被触发一次。

3.页面滚动 onPageScroll

监听用户滑动页面事件,参数为 Object,包含 scrollTop 字段,表示页面在垂直方向已滚动的距离(单位px)。

4.用户转发 onShareAppMessage

只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮,在用户点击转发按钮的时候会调用,此事件需要return一个Object,包含title和path两个字段,用于自定义转发内容,如代码清单3-13所示。

6.页面跳转和路由
路由方式触发时机路由前页面生命周期路由后页面生命周期
初始化小程序打开的第一个页面onLoad, onShow
打开新页面 调用API wx.navigateToonHideonLoad, onShow
页面重定向 调用API wx.redirectToonUnloadonLoad, onShow
页面返回 调用API wx.navigateBackonUnloadonShow
重启动 调用API wx.reLaunchonUnloadonLoad, onShow
作者:qinorgsi原文地址:https://segmentfault.com/a/1190000042480244

%s 个评论

要回复文章请先登录注册