小程序

小程序

简介

何为小程序

  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模板
{{time}}

//JS
Page({
    data: {
        time: (new.Date()).toString()
    },
    })

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

//WXML模板
{{time}}

//JS
Page({
    data: {
        height: 1
    },
    })

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

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

1. 三元运算

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

2. 字符串拼接

{{
    name: world
    }}

//WXML模板
{{"hello" + name}}

输出hello world

3. 算术运算

{
    a:10,
    b:2,
    c:5,
    d:2
}

{{a + b}} + {{c}} + d

输出:12 + 5 + d

4. 条件逻辑

if else,例子如下:

6
1
3

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


1
2
4.列表渲染

1. 默认

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


{{index}}: {{item.messge}}


Page({
  data: {
    array: [{
      message: 'foo',
    }, {
      message: 'bar'
    }]
  }
})

输出:
0:foo
1:bar

2.自定义

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


  {{idx}}: {{itemName.message}}

3.块


   {{index}}: 
   {{item}} 

WXSS样式

1. 文件组成

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

2. 尺寸单位

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

小程序_第1张图片

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

样式使用方式

  1. 引用样式

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

选择器

类型 选择器 样例 样例描述
类选择器 .class .intro 选择所有拥有 class="intro" 的组件
id选择器 #id #firstname 选择拥有 id="firstname" 的组件
元素选择器 element view checkbox 选择所有文档的 view 组件和所有的 checkbox 组件
伪元素选择器 ::after view::after 在 view 组件后边插入内容
伪元素选择器 ::before view::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模板

    a
    b
    c


//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模板
{{msg}}

//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模板

hello world
程序与页面

程序

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

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

生命周期

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

打开场景

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

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

字段 类型 描述
path String 打开小程序的页面路径
query Object 打开小程序的页面参数query
scene Number 打开小程序的场景值,详细场景值请参考小程序官方文档
shareTicket String shareTicket,详见小程序官方文档

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参数,大致参数如下;
参数属性 类型 描述
data Object 页面的初始数据
onLoad Function 生命周期函数--监听页面加载,触发时机早于onShow和onReady
onReady Function 生命周期函数--监听页面初次渲染完成
onShow Function 生命周期函数--监听页面显示,触发事件早于onReady
onHide Function 生命周期函数--监听页面隐藏
onUnload Function 生命周期函数--监听页面卸载
onPullDownRefresh Function 页面相关事件处理函数--监听用户下拉动作
onReachBottom Function 页面上拉触底事件的处理函数
onShareAppMessage Function 用户点击右上角转发
onPageScroll Function 页面滚动触发事件的处理函数
其他 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.navigateTo onHide onLoad, onShow
页面重定向 调用 API wx.redirectTo onUnload onLoad, onShow
页面返回 调用 API wx.navigateBack onUnload onShow
重启动 调用 API wx.reLaunch onUnload onLoad, onShow

你可能感兴趣的:(小程序)