微信小程序开发学习笔记(三)——WXSS、WXS(WeiXin Script)、生命周期

一、WXSS (WeiXin Style Sheets)

WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。

WXSS 用来决定 WXML 的组件应该怎么显示。

为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。

与 CSS 相比,WXSS 扩展的特性有:

  • 尺寸单位
  • 样式导入

1.1、尺寸单位

  • rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
设备rpx换算px (屏幕宽度/750)px换算rpx (750/屏幕宽度)
iPhone5 1rpx = 0.42px 1px = 2.34rpx
iPhone6 1rpx = 0.5px 1px = 2rpx
iPhone6 Plus 1rpx = 0.552px 1px = 1.81rpx

建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。

注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。

<view>
  Hello RPX!
</view>
view{
  width: 750rpx;
  background:orange;
  height: 750rpx;
  font-size: 70rpx;
}

小屏幕时:

 大屏幕时:

 屏幕大时字体、高与宽都同时变大,rpx是响应式的相对刻度单位。

1.2、样式导入

使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。

示例代码:

/** common.wxss **/
.small-p {
  padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {
  padding:15px;
}
pages/css/common.wxss
.title{
  color:lightyellow;
}

pages/hello/index.wxml

<view class="title">
  Hello RPX!
</view>

pages/hello/index.wxss

view{
  width: 750rpx;
  background:orange;
  height: 750rpx;
  font-size: 70rpx;
}
@import"../css/common.wxss"

运行结果:

1.3、内联样式

框架组件上支持使用 style、class 属性来控制组件的样式。

  • style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。
<view style="color:{{color}};" />
<view style="background: {{color}}; height: 100px;">
  背景是什么颜色:
  <input value="{{color}}" bindinput="inputHandle" />
  {{color}}
</view>
const page={
  data:{
    users:[{id:1001,name:"jack",age:18},
    {id:1002,name:"mark",age:17},
    {id:1003,name:"rose",age:20},
    {id:1004,name:"lili",age:15},
    {id:1005,name:"lucy",age:22}],
    color:""
  },
  inputHandle(e){
    this.setData({color:e.detail.value})
  }
};
Page(page);

  • class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上.,样式类名之间用空格分隔。
<view class="normal_view" />
<view wx:for="{{users}}" wx:key="id" class="{{index%2===1?'bg1':'bg2'}}">
  {{item.name}}
</view>

<view wx:for="{{users}}" wx:key="id" class="{{'bg'+(index%2+1)}}">
  {{item.name}}
</view>
view{
  padding: 20rpx;
  margin: 20rpx;
}
.bg1{
  background: lightgreen;
}
.bg2{
  background: lightskyblue;
}
const page={
  data:{
    users:[{id:1001,name:"jack",age:18},
    {id:1002,name:"mark",age:17},
    {id:1003,name:"rose",age:20},
    {id:1004,name:"lili",age:15},
    {id:1005,name:"lucy",age:22}],
    color:""
  }
};
Page(page);

1.4、选择器

目前支持的选择器有:

选择器样例样例描述
.class .intro 选择所有拥有 class="intro" 的组件
#id #firstname 选择拥有 id="firstname" 的组件
element view 选择所有 view 组件
element, element view, checkbox 选择所有文档的 view 组件和所有的 checkbox 组件
::after view::after 在 view 组件后边插入内容
::before view::before 在 view 组件前边插入内容

1.5、全局样式与局部样式

定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。

app.wxss中的样式可以作用于每一个页面中

app.wxss中的内容如下:

.blue{
  font-size: 50rpx;
  color: blue;
}

hello/index.wxml

<view class="blue">
  blue是全局样式
</view>

counter/index.wxml

<!--pages/counter/index.wxml-->
<include src="../templates/header"></include>

<view class="blue">
  blue是全局样式
</view>

<view class="counter">
 <view class="title"><text>计数器</text></view>
 <view>{{count}}</view>
 <view>
  <button type="primary" bindtap="onCount">点击count++</button>
 </view>
</view>

<import src="../templates/card.wxml" />
<template is="card" data="{{id:1002,name:'王五',age:19}}" />
<include src="../templates/footer"></include>

运行结果:

1.6、background-image问题

(1)、微信小程序view background-image 不能够直接显示本地

[渲染层网络层错误] pages/hello/index.wxss 中的本地资源图片无法通过 WXSS 获取,可以使用网络图片,或者 base64,或者使用<image/>标签。请参考文档:https://developers.weixin.qq.com/miniprogram/dev/qa.html#%E6%9C%AC%E5%9C%B0%E8%B5%84%E6%BA%90%E6%97%A0%E6%B3%95%E9%80%9A%E8%BF%87-wxss-%E8%8E%B7%E5%8F%96
2 | width: 750rpx;
3 | height: 750rpx;
> 4 | background-image: url(../../images/haha.jpg);
| ^
5 | background-color: oldlace;
6 | }(env: Windows,mp,1.06.2303220; lib: 2.19.4)

 

(2)、但是可以直接显示网络图片

https://bkimg.cdn.bcebos.com/pic/0bd162d9f2d3572c11df08d4e75a742762d0f703652b?x-bce-process=image/resize,m_lfit,w_536,limit_1
假定需要下面这张图:

图片的url是:

https://img2023.cnblogs.com/blog/63651/202304/63651-20230427095037374-1403577959.png

(3)、将本地图片转化成base64方式引用图片

二、WXS(WeiXin Script)

WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。

WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。

2.1、WXS 模块

WXS 代码可以编写在 wxml 文件中的 <wxs> 标签内,或以 .wxs 为后缀名的文件内。

2.1.1、模块

每一个 .wxs 文件和 <wxs> 标签都是一个单独的模块。

每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。

一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现。

2.1.2、.wxs 文件

微信开发者工具里面,右键可以直接创建 .wxs 文件,在其中直接编写 WXS 脚本。

示例代码:

// /pages/comm.wxs

var foo = "'hello world' from comm.wxs";
var bar = function(d) {
  return d;
}
module.exports = {
  foo: foo,
  bar: bar
};

上述例子在 /pages/comm.wxs 的文件里面编写了 WXS 代码。该 .wxs 文件可以被其他的 .wxs 文件 或 WXML 中的 <wxs> 标签引用。

module 对象

每个 wxs 模块均有一个内置的 module 对象。

属性

  • exports: 通过该属性,可以对外共享本模块的私有变量与函数。

定义方法一:

pages/common.wxs

//定义变量
var name="张三";
//定义函数表达式
var show=function(info){
  var msg="你好,"+info;
  console.log(msg);
  return msg;
}
//导出
module.exports={name:name,show:show}

请不要使用ES6的语法内容

pages/hello/index.wxml

<wxs src="../common.wxs" module="greeting"></wxs>
<view>
{{greeting.show(greeting.name)}}
</view>

结果:

示例代码:

在开发者工具中预览效果

// /pages/tools.wxs

var foo = "'hello world' from tools.wxs";
var bar = function (d) {
  return d;
}
module.exports = {
  FOO: foo,
  bar: bar,
};
module.exports.msg = "some msg";
<!-- page/index/index.wxml -->

<wxs src="./../tools.wxs" module="tools" />
<view> {{tools.msg}} </view>
<view> {{tools.bar(tools.FOO)}} </view>

页面输出:

some msg
'hello world' from tools.wxs

require函数

.wxs模块中引用其他 wxs 文件模块,可以使用 require 函数。

引用的时候,要注意如下几点:

  • 只能引用 .wxs 文件模块,且必须使用相对路径。
  • wxs 模块均为单例,wxs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 wxs 模块对象。
  • 如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。

示例代码:

在开发者工具中预览效果

// /pages/tools.wxs

var foo = "'hello world' from tools.wxs";
var bar = function (d) {
  return d;
}
module.exports = {
  FOO: foo,
  bar: bar,
};
module.exports.msg = "some msg";
// /pages/logic.wxs

var tools = require("./tools.wxs");

console.log(tools.FOO);
console.log(tools.bar("logic.wxs"));
console.log(tools.msg);
<!-- /page/index/index.wxml -->

<wxs src="./../logic.wxs" module="logic" />

控制台输出:

'hello world' from tools.wxs
logic.wxs
some msg

maths.wxs
var add=function(n1,n2){
  console.log(n1+"+"+n2+"="+(n1+n2));
  return n1+n2;
}
module.exports={add:add}

common.wxs

//导入maths模块
var maths=require("maths.wxs");

var calc=function(){
  //生成0-100间的随机数
  var n1=Math.floor(Math.random()*100);
  var n2=Math.floor(Math.random()*100);
  //调用maths模块下的add方法
  return maths.add(n1,n2);
}

module.exports={calc:calc}

index.wxml

<wxs src="../common.wxs" module="common"></wxs>
<view>
  {{common.calc()}}
</view>

运行结果:

2.1.3、<wxs> 标签

属性名类型默认值说明
module String   当前 <wxs> 标签的模块名。必填字段。
src String   引用 .wxs 文件的相对路径。仅当本标签为单闭合标签标签的内容为空时有效。

module 属性

module 属性是当前 <wxs> 标签的模块名。在单个 wxml 文件内,建议其值唯一。有重复模块名则按照先后顺序覆盖(后者覆盖前者)。不同文件之间的 wxs 模块名不会相互覆盖。

module 属性值的命名必须符合下面两个规则:

  • 首字符必须是:字母(a-zA-Z),下划线(_)
  • 剩余字符可以是:字母(a-zA-Z),下划线(_), 数字(0-9)

示例代码:

在开发者工具中预览效果

<!--wxml-->

<wxs module="foo">
var some_msg = "hello world";
module.exports = {
  msg : some_msg,
}
</wxs>
<view> {{foo.msg}} </view>

页面输出:

hello world

上面例子声明了一个名字为 foo 的模块,将 some_msg 变量暴露出来,供当前页面使用。

<wxs module="m1">
var name="jack";  //定义变量name
var hi=function(info){  //定义hi函数
  return "Hello "+info;
}
module.exports={name:name,hi:hi}  //当前模块导出
</wxs>

<view>
  <!-- 调用模块m1中的方法与属性 -->
  {{m1.hi(m1.name)}}  
</view>

src 属性

src 属性可以用来引用其他的 wxs 文件模块。

引用的时候,要注意如下几点:

  • 只能引用 .wxs 文件模块,且必须使用相对路径。
  • wxs 模块均为单例,wxs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 wxs 模块对象。
  • 如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。

示例代码:

在开发者工具中预览效果

// /pages/index/index.js

Page({
  data: {
    msg: "'hello wrold' from js",
  }
})
<!-- /pages/index/index.wxml -->

<wxs src="./../comm.wxs" module="some_comms"></wxs>
<!-- 也可以直接使用单标签闭合的写法
<wxs src="./../comm.wxs" module="some_comms" />
-->

<!-- 调用 some_comms 模块里面的 bar 函数,且参数为 some_comms 模块里面的 foo -->
<view> {{some_comms.bar(some_comms.foo)}} </view>
<!-- 调用 some_comms 模块里面的 bar 函数,且参数为 page/index/index.js 里面的 msg -->
<view> {{some_comms.bar(msg)}} </view>

页面输出:

'hello world' from comm.wxs
'hello wrold' from js

上述例子在文件 /page/index/index.wxml 中通过 <wxs> 标签引用了 /page/comm.wxs 模块。

2.1.4、注意事项

  • <wxs> 模块只能在定义模块的 WXML 文件中被访问到。使用 <include> 或 <import> 时,<wxs> 模块不会被引入到对应的 WXML 文件中。
  • <template> 标签中,只能使用定义该 <template> 的 WXML 文件中定义的 <wxs> 模块。

2.2、变量

2.2.1、概念

  • WXS 中的变量均为值的引用。
  • 没有声明的变量直接赋值使用,会被定义为全局变量。
  • 如果只声明变量而不赋值,则默认值为 undefined
  • var表现与javascript一致,会有变量提升。
var foo = 1;
var bar = "hello world";
var i; // i === undefined

上面代码,分别声明了 foo、 bar、 i 三个变量。然后,foo 赋值为数值 1 ,bar 赋值为字符串 "hello world"

1、没有块级作用域

 2、javascript有函数级作用域

 上面的示例中因为有函数级作用域,x在函数中,所有函数外访问不到。

3、没有声明的变量直接赋值使用,会被定义为全局变量。

 因为x在定义时没有var,直接使用,x是一个全局变量,所以在函数外又能访问到。

4、变量如果定义了但不赋值,默认值是undefined

 5、wxs中与javascript一样会有代码提升

因为有代码提升,javascript运行环境会将定义的定义提升到最前面,上面的代码相当于:
var x=undefined;
console.log(x);
x=100;

2.2.2、变量名

变量命名必须符合下面两个规则:

  • 首字符必须是:字母(a-zA-Z),下划线(_)
  • 剩余字符可以是:字母(a-zA-Z),下划线(_), 数字(0-9)

2.2.3、保留标识符

以下标识符不能作为变量名:

delete
void
typeof

null
undefined
NaN
Infinity
var
if
else
true
false
require
this
function
arguments
return
for
while
do
break
continue
switch
case
default

2.3、注释

WXS 主要有 3 种注释的方法。

示例代码:

<!-- wxml -->
<wxs module="sample">
// 方法一:单行注释

/*
方法二:多行注释
*/

/*
方法三:结尾注释。即从 /* 开始往后的所有 WXS 代码均被注释

var a = 1;
var b = 2;
var c = "fake";

</wxs>

上述例子中,所有 WXS 代码均被注释掉了。

方法三 和 方法二 的唯一区别是,没有 */ 结束符。

2.4、运算符

2.4.1、基本运算符

示例代码:

var a = 10, b = 20;

// 加法运算
console.log(30 === a + b);
// 减法运算
console.log(-10 === a - b);
// 乘法运算
console.log(200 === a * b);
// 除法运算
console.log(0.5 === a / b);
// 取余运算
console.log(10 === a % b);
  • 加法运算(+)也可以用作字符串的拼接。
var a = '.w' , b = 'xs';

// 字符串拼接
console.log('.wxs' === a + b);

2.4.2、一元运算符

示例代码:

var a = 10, b = 20;

// 自增运算
console.log(10 === a++);
console.log(12 === ++a);
// 自减运算
console.log(12 === a--);
console.log(10 === --a);
// 正值运算
console.log(10 === +a);
// 负值运算
console.log(0-10 === -a);
// 否运算
console.log(-11 === ~a);
// 取反运算
console.log(false === !a);
// delete 运算
console.log(true === delete a.fake);
// void 运算
console.log(undefined === void a);
// typeof 运算
console.log("number" === typeof a);

2.4.3、位运算符

示例代码:

var a = 10, b = 20;

// 左移运算
console.log(80 === (a << 3));
// 带符号右移运算
console.log(2 === (a >> 2));
// 无符号右移运算
console.log(2 === (a >>> 2));
// 与运算
console.log(2 === (a & 3));
// 异或运算
console.log(9 === (a ^ 3));
// 或运算
console.log(11 === (a | 3));

2.4.5、比较运算符

示例代码:

var a = 10, b = 20;

// 小于
console.log(true === (a < b));
// 大于
console.log(false === (a > b));
// 小于等于
console.log(true === (a <= b));
// 大于等于
console.log(false === (a >= b));

2.4.6、等值运算符

示例代码:

var a = 10, b = 20;

// 等号
console.log(false === (a == b));
// 非等号
console.log(true === (a != b));
// 全等号
console.log(false === (a === b));
// 非全等号
console.log(true === (a !== b));
//==比较时会进行类型转换
//===比较时不会进行类型转换
//推荐使用===
console.log(3=="3");  //比较前会先将两边的类型转换成一致,再比值
console.log(3==="3");  //直接比较,不转换类型,因为类型不一致,所以为false

console.log(3!="3");  //比较前会先将两边的类型转换成一致,再比值
console.log(3!=="3");  //直接比较,不转换类型,因为类型不一致,所以为false

2.4.7、赋值运算符

示例代码:

var a = 10;

a = 10; a *= 10;
console.log(100 === a);
a = 10; a /= 5;
console.log(2 === a);
a = 10; a %= 7;
console.log(3 === a);
a = 10; a += 5;
console.log(15 === a);
a = 10; a -= 11;
console.log(-1 === a);
a = 10; a <<= 10;
console.log(10240 === a);
a = 10; a >>= 2;
console.log(2 === a);
a = 10; a >>>= 2;
console.log(2 === a);
a = 10; a &= 3;
console.log(2 === a);
a = 10; a ^= 3;
console.log(9 === a);
a = 10; a |= 3;
console.log(11 === a);

2.4.8、二元逻辑运算符

示例代码:

var a = 10, b = 20;

// 逻辑与
console.log(20 === (a && b));
// 逻辑或
console.log(10 === (a || b));

2.4.9、其他运算符

示例代码:

var a = 10, b = 20;

//条件运算符
console.log(20 === (a >= 10 ? a + 10 : b + 10));
//逗号运算符
console.log(20 === (a, b));

2.5、语句

2.5.1、if 语句

在 WXS 中,可以使用以下格式的 if 语句 :

  • if (expression) statement : 当 expression 为 truthy 时,执行 statement

  • if (expression) statement1 else statement2 : 当 expression 为 truthy 时,执行 statement1。 否则,执行 statement2

  • if ... else if ... else statementN 通过该句型,可以在 statement1 ~ statementN 之间选其中一个执行。

示例语法:

// if ...

if (表达式) 语句;

if (表达式)
  语句;

if (表达式) {
  代码块;
}


// if ... else

if (表达式) 语句;
else 语句;

if (表达式)
  语句;
else
  语句;

if (表达式) {
  代码块;
} else {
  代码块;
}

// if ... else if ... else ...

if (表达式) {
  代码块;
} else if (表达式) {
  代码块;
} else if (表达式) {
  代码块;
} else {
  代码块;
}

2.5.2、switch 语句

示例语法:

switch (表达式) {
  case 变量:
    语句;
  case 数字:
    语句;
    break;
  case 字符串:
    语句;
  default:
    语句;
}
  • default 分支可以省略不写。
  • case 关键词后面只能使用:变量数字字符串

示例代码:

var exp = 10;

switch ( exp ) {
case "10":
  console.log("string 10");
  break;
case 10:
  console.log("number 10");
  break;
case exp:
  console.log("var exp");
  break;
default:
  console.log("default");
}

输出:

number 10

2.5.3、for 语句

示例语法:

for (语句; 语句; 语句)
  语句;

for (语句; 语句; 语句) {
  代码块;
}
  • 支持使用 breakcontinue 关键词。

示例代码:

for (var i = 0; i < 3; ++i) {
  console.log(i);
  if( i >= 1) break;
}

输出:

0
1

2.5.4、while 语句

示例语法:

while (表达式)
  语句;

while (表达式){
  代码块;
}

do {
  代码块;
} while (表达式)
  • 表达式为 true 时,循环执行语句代码块
  • 支持使用 breakcontinue 关键词。

2.6、数据类型

WXS 语言目前共有以下几种数据类型:

  • number : 数值
  • string :字符串
  • boolean:布尔值
  • object:对象
  • function:函数
  • array : 数组
  • date:日期
  • regexp:正则

2.6.1、number

语法

number 包括两种数值:整数,小数。

var a = 10;
var PI = 3.141592653589793;

属性

  • constructor:返回字符串 "Number"

方法

  • toString
  • toLocaleString
  • valueOf
  • toFixed
  • toExponential
  • toPrecision

以上方法的具体使用请参考 ES5 标准。

2.6.2、string

语法

string 有两种写法:

'hello world';
"hello world";

属性

  • constructor:返回字符串 "String"
  • length

除constructor外属性的具体含义请参考 ES5 标准。

方法

  • toString
  • valueOf
  • charAt
  • charCodeAt
  • concat
  • indexOf
  • lastIndexOf
  • localeCompare
  • match
  • replace
  • search
  • slice
  • split
  • substring
  • toLowerCase
  • toLocaleLowerCase
  • toUpperCase
  • toLocaleUpperCase
  • trim

以上方法的具体使用请参考 ES5 标准。

2.6.3、boolean

语法

布尔值只有两个特定的值:true 和 false

属性

  • constructor:返回字符串 "Boolean"

方法

  • toString
  • valueOf

以上方法的具体使用请参考 ES5 标准。

2.6.4、object

语法

object 是一种无序的键值对。使用方法如下所示:

var o = {} //生成一个新的空对象

//生成一个新的非空对象
o = {
  'string'  : 1,  //object 的 key 可以是字符串
  const_var : 2,  //object 的 key 也可以是符合变量定义规则的标识符
  func      : {}, //object 的 value 可以是任何类型
};

//对象属性的读操作
console.log(1 === o['string']);
console.log(2 === o.const_var);

//对象属性的写操作
o['string']++;
o['string'] += 10;
o.const_var++;
o.const_var += 10;

//对象属性的读操作
console.log(12 === o['string']);
console.log(13 === o.const_var);

属性

  • constructor:返回字符串 "Object"
console.log("Object" === {k:"1",v:"2"}.constructor)

方法

  • toString:返回字符串 "[object Object]"

2.6.5、function

语法

function 支持以下的定义方式:

//方法 1
function a (x) {
  return x;
}

//方法 2
var b = function (x) {
  return x;
}

function 同时也支持以下的语法(匿名函数,闭包等):

var a = function (x) {
  return function () { return x;}
}

var b = a(100);
console.log( 100 === b() );

arguments

function 里面可以使用 arguments 关键词。该关键词目前只支持以下的属性:

  • length: 传递给函数的参数个数。
  • [index]: 通过 index 下标可以遍历传递给函数的每个参数。

示例代码:

var a = function(){
  console.log(3 === arguments.length);
  console.log(100 === arguments[0]);
  console.log(200 === arguments[1]);
  console.log(300 === arguments[2]);
};
a(100,200,300);

属性

  • constructor:返回字符串 "Function"
  • length:返回函数的形参个数。

方法

  • toString:返回字符串 "[function Function]"

示例代码:

var func = function (a,b,c) { }

console.log("Function" === func.constructor);
console.log(3 === func.length);
console.log("[function Function]" === func.toString());

2.6.6、array

语法

array 支持以下的定义方式:

var a = [];      //生成一个新的空数组

a = [1,"2",{},function(){}];  //生成一个新的非空数组,数组元素可以是任何类型

属性

  • constructor:返回字符串 "Array"
  • length

除constructor外属性的具体含义请参考 ES5 标准。

方法

  • toString
  • concat
  • join
  • pop
  • push
  • reverse
  • shift
  • slice
  • sort
  • splice
  • unshift
  • indexOf
  • lastIndexOf
  • every
  • some
  • forEach
  • map
  • filter
  • reduce
  • reduceRight

以上方法的具体使用请参考 ES5 标准。

2.6.7、date

语法

生成 date 对象需要使用 getDate函数, 返回一个当前时间的对象。

getDate()
getDate(milliseconds)
getDate(datestring)
getDate(year, month[, date[, hours[, minutes[, seconds[, milliseconds]]]]])
  • 参数
    • milliseconds: 从1970年1月1日00:00:00 UTC开始计算的毫秒数
    • datestring: 日期字符串,其格式为:"month day, year hours:minutes:seconds"

示例代码:

var date = getDate(); //返回当前时间对象

date = getDate(1500000000000);
// Fri Jul 14 2017 10:40:00 GMT+0800 (中国标准时间)
date = getDate('2017-7-14');
// Fri Jul 14 2017 00:00:00 GMT+0800 (中国标准时间)
date = getDate(2017, 6, 14, 10, 40, 0, 0);
// Fri Jul 14 2017 10:40:00 GMT+0800 (中国标准时间)

属性

  • constructor:返回字符串 “Date”。

方法

  • toString
  • toDateString
  • toTimeString
  • toLocaleString
  • toLocaleDateString
  • toLocaleTimeString
  • valueOf
  • getTime
  • getFullYear
  • getUTCFullYear
  • getMonth
  • getUTCMonth
  • getDate
  • getUTCDate
  • getDay
  • getUTCDay
  • getHours
  • getUTCHours
  • getMinutes
  • getUTCMinutes
  • getSeconds
  • getUTCSeconds
  • getMilliseconds
  • getUTCMilliseconds
  • getTimezoneOffset
  • setTime
  • setMilliseconds
  • setUTCMilliseconds
  • setSeconds
  • setUTCSeconds
  • setMinutes
  • setUTCMinutes
  • setHours
  • setUTCHours
  • setDate
  • setUTCDate
  • setMonth
  • setUTCMonth
  • setFullYear
  • setUTCFullYear
  • toUTCString
  • toISOString
  • toJSON

以上方法的具体使用请参考 ES5 标准。

2.6.8、regexp

语法

生成 regexp 对象需要使用 getRegExp函数。

getRegExp(pattern[, flags])
  • 参数:
    • pattern: 正则表达式的内容。
    • flags:修饰符。该字段只能包含以下字符:
      • g: global
      • i: ignoreCase
      • m: multiline。

示例代码:

var a = getRegExp("x", "img");
console.log("x" === a.source);
console.log(true === a.global);
console.log(true === a.ignoreCase);
console.log(true === a.multiline);

属性

  • constructor:返回字符串 "RegExp"
  • source
  • global
  • ignoreCase
  • multiline
  • lastIndex

除constructor外属性的具体含义请参考 ES5 标准。

方法

  • exec
  • test
  • toString

以上方法的具体使用请参考 ES5 标准。

2.6.9、数据类型判断

constructor 属性

数据类型的判断可以使用 constructor 属性。

示例代码:

var number = 10;
console.log( "Number" === number.constructor );

var string = "str";
console.log( "String" === string.constructor );

var boolean = true;
console.log( "Boolean" === boolean.constructor );

var object = {};
console.log( "Object" === object.constructor );

var func = function(){};
console.log( "Function" === func.constructor );

var array = [];
console.log( "Array" === array.constructor );

var date = getDate();
console.log( "Date" === date.constructor );

var regexp = getRegExp();
console.log( "RegExp" === regexp.constructor );

typeof

使用 typeof 也可以区分部分数据类型。

示例代码:

var number = 10;
var boolean = true;
var object = {};
var func = function(){};
var array = [];
var date = getDate();
var regexp = getRegExp();

console.log( 'number' === typeof number );
console.log( 'boolean' === typeof boolean );
console.log( 'object' === typeof object );
console.log( 'function' === typeof func );
console.log( 'object' === typeof array );
console.log( 'object' === typeof date );
console.log( 'object' === typeof regexp );

console.log( 'undefined' === typeof undefined );
console.log( 'object' === typeof null );

2.7、基础类库

2.7.1、console

console.log 方法用于在 console 窗口输出信息。它可以接受多个参数,将它们的结果连接起来输出。

2.7.2、Math

属性

  • E
  • LN10
  • LN2
  • LOG2E
  • LOG10E
  • PI
  • SQRT1_2
  • SQRT2

以上属性的具体使用请参考 ES5 标准。

方法

  • abs
  • acos
  • asin
  • atan
  • atan2
  • ceil
  • cos
  • exp
  • floor
  • log
  • max
  • min
  • pow
  • random
  • round
  • sin
  • sqrt
  • tan

以上方法的具体使用请参考 ES5 标准。

2.7.3、JSON

方法

  • stringify(object): 将 object 对象转换为 JSON 字符串,并返回该字符串。
  • parse(string): 将 JSON 字符串转化成对象,并返回该对象。

示例代码:


console.log(undefined === JSON.stringify());
console.log(undefined === JSON.stringify(undefined));
console.log("null"===JSON.stringify(null));

console.log("111"===JSON.stringify(111));
console.log('"111"'===JSON.stringify("111"));
console.log("true"===JSON.stringify(true));
console.log(undefined===JSON.stringify(function(){}));


console.log(undefined===JSON.parse(JSON.stringify()));
console.log(undefined===JSON.parse(JSON.stringify(undefined)));
console.log(null===JSON.parse(JSON.stringify(null)));

console.log(111===JSON.parse(JSON.stringify(111)));
console.log("111"===JSON.parse(JSON.stringify("111")));
console.log(true===JSON.parse(JSON.stringify(true)));

console.log(undefined===JSON.parse(JSON.stringify(function(){})));

2.7.4、Number

属性

  • MAX_VALUE
  • MIN_VALUE
  • NEGATIVE_INFINITY
  • POSITIVE_INFINITY

以上属性的具体使用请参考 ES5 标准。

2.7.5、Date

属性

  • parse
  • UTC
  • now

以上属性的具体使用请参考 ES5 标准。

2.7.6、Global

属性

  • NaN
  • Infinity
  • undefined

以上属性的具体使用请参考 ES5 标准。

方法

  • parseInt
  • parseFloat
  • isNaN
  • isFinite
  • decodeURI
  • decodeURIComponent
  • encodeURI
  • encodeURIComponent

以上方法的具体使用请参考 ES5 标准。

2.8、WXS与JS的区别

1、WXS 中不支持 let和const;不支持箭头函数、一切ES6及以后新增加的内容都不支持。

2、WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API。

3、由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。

4、WXS只支持到JS5版本,不支持ES6

5、WXS使用了JS的严格模式strict mode

6、WXS 里,遍历数组只能通过for实现,而JS中的for in和for of不被支持,对于需要循环处理数据的场景,也可以通过数组的forEach方法实现遍历:

 var ary = [0, 1, 2];
 ary.forEach(function(i) {
  console.log(i);
 })
7、WXS只提供给开发者5个基础类库,分别是 console,Math,JSON,Number,Date,以及一些常用的全局变量和全局函数,数量不多,但已经能满足基本的数据操作要求,而对于复杂的数据操作,比如类定义和继承等,还是需要依靠逻辑层的 JS 脚本完成。

8、由于WXS先天不支持使用 Array 对象,因此我们平常用于判断数组类型变量的语句[] instanceof Array也就不能使用了,而typeof []的输出结果是"object",并不能满足实际的开发要求。所幸我们还可以使用变量的 「constructor」属性进行类型判断:

[].constructor === Array  //true
9、小程序的架构分成了逻辑层和视图层,WXS 与JavaScript还有一个差异在于,它与WXML一同们于视图层,运行于同一个线程内,因此减少了跨线程通信的开销。这也是我们之所以优先采用WXS处理数据的原因之一。
10、小程序在Android上,使用V8引擎解析和渲染 JavaScript; 而在iOS上,则是使用 JavaScriptCore,这两者在解析性能的表现上差异比较大,相对来说 V8 的性能比 JSC 要好得多,那么在 IOS 的小程序中,使用脱离 JavaScript 环境的 WXS,就会使性能有更多的提升,这也是WXS文档中提及 “在 iOS 设备上小程序内的 wxs 会比 javascript 代码快 2 ~ 20 倍” 的具体原因
11、不要使用DOM与BOM,使用ES5

三、生命周期

小程序的生命周期说白了就是指程序从创建、到开始、暂停、唤起、停止、卸载的过程。

微信小程序生命周期包含了三个部分:

    • 应用级别的生命周期(整个App的生命周期)
    • 页面级别的生命周期(单个页面(page)的生命周期)
    • 组件基本的生命周期(组件(component)的生命周期)在这里插入图片描述

3.1、小程序的启动流程

通过了解小程序的启动流程,可以了解小程序的代码执行顺序。每个小程序都需要在 app.js 中调用 App() 方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等,而且整个小程序只有一个 App 实例,是全部页面共享的。开发者可以通过 getApp() 方法获取到全局唯一的 App 实例,获取 App 上的数据或调用开发者注册在 App 上的函数。官方文档

小程序的启动流程简述:小程序在启动的时候会先下载小程序包,再启动小程序,然后加载 app.json 全局配置文件,然后在 app.js 中调用 App() 方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。

3.2、app生命周期

app.js 文件下小程序的 App 相关生命周期代码如下:

// app.js
App({
  //小程序初始化完成,会执行的生命周期函数 onLaunch
  onLaunch (options) {    // Do something initial when launch.    },    //例如网络请求、获取用户信息等:异步
  //小程序界面显示出来,会执行的生命周期函数 onShow
  onShow (options) {    // Do something when show.    },
  //小程序界面被隐藏时,会执行的生命周期函数 onHide,隐藏后小程序会在后台存活两个小时,该时间内打开小程序不会重新加载
  onHide () {    // Do something when hide.    },
  //小程序中发生错误时,会执行的生命周期函数 onError
  onError (msg) {    console.log(msg)    },
  globalData: 'I am global data'    //全局数据,可以在其他页面通过getApp()获取App()产生的实例对象
                                    //const app = getApp();    console.log(app.globalData.name);
})

注册完 App 实例后,会加载自定义组件并注册,之后会加载某一个页面(一般是app.json配置中的pages数组的第一个路径的页面,如果配置了编译环境的话,就会在该配置环境下先加载指定页面),首先会加载某个页面的 json 文件,读取该文件下的相关页面配置,然后是渲染 wxml 文件,将代码转化成 JS 对象,进而转化成 真实DOM树,然后把 DOM 树渲染出来。而且也会加载某个页面的 js 文件(双线程模型),会调用 Page() 函数,并绑定 Page 生命周期函数。

每个小程序都需要在 app.js 中调用 App() 方法注册小程序实例,在注册时,可以绑定对应的生命周期函数,在小程序的生命周期函数中,执行对应的代码,具体的参数及介绍可以参考一下 官方文档。

必须在 app.js 中调用,必须调用且只能调用一次。里面包含了几个app的生命周期钩子:

    1. onLaunch: 小程序初始化完成时触发,全局只触发一次
      • 云开发的初始化 方便其他页面直接调用云开发的SDK
      • 发送请求获取用户的个人信息 方便其他页面使用
      • 获取本地存储数据 方便其他页面使用
      • //注册小程序
        App({
          onLaunch(options){
            console.log("App->onLaunch:应用程序加载完成",options);
          }
        })
      • 添加query参数
      •  

         获取参数

      • .页面中获取启动对象
      • //注册页面
        Page({
          launchHandle(){
            //获得启动参数
            const options=wx.getLaunchOptionsSync();
            console.log(options);
          }
        });

    2. onShow:小程序启动或切前台显示时触发。
      • 重新启动定时器 继续定时执行功能
      • 重新触发异步 获取新的数据
      • 重新启动播放器等
        .
    3. onHide:小程序从前台进入后台时触发(如 切换到其他的App)。
      • 当暂停定时器
      • 暂停视频音频的播放
    4. onError:小程序发生脚本错误或 API 调用报错时触发。
      • 收集错误信息 发送到后台 进行错误日志的记录
      • 弹出窗口提示用户
      • //注册小程序
        App({
          onLaunch(options){
            console.log("App->onLaunch:应用程序加载完成",options);
          },
          onShow(options){
            console.log("App->onShow:小程序页面显示",options);
          },
          onHide(){
            console.log("App->onHide:小程序页面隐藏");
          },
          onError(err){
            console.log('应用程序发生了错误',err);
          },
          //全局数据
          globalData:{
            a:100,
            b:200
          }
        })
        //注册页面
        Page({
          launchHandle(){
            //获得启动参数
            const options=wx.getLaunchOptionsSync();
            console.log(options);
          },
          errorHandler(){
            throw new Error("发生了异常!");
          }
        });

    5. onPageNotFound:小程序要打开的页面不存在时触发。
      • 监听报错,弹出窗口提示用户
      • 监听报错,重新跳转页面
        .
    6. onUnhandledRejection:小程序有未处理的 Promise 拒绝时触发。
      • 用在统一捕获处理 可以在该生命周期中处理错误情况 ,一般是由于异步代码出错导致的
        .
    7. onThemeChange:系统切换主题时触发。
      • 让小程序可以跟着主题的切换 也改变小程序的UI风格,使之体验更好!

示例:globalData

 app.js

//注册小程序
App({
  onLaunch(options){
    console.log("App->onLaunch:应用程序加载完成",options);
  },
  onShow(options){
    console.log("App->onShow:小程序页面显示",options);
  },
  onHide(){
    console.log("App->onHide:小程序页面隐藏");
  },
  onError(err){
    console.log('应用程序发生了错误',err);
  },
  //全局数据
  globalData:{
    a:100,
    b:200
  }
})

hello/index.js

//注册页面
Page({
  getAppData(e)
  {
    //获取应用实例
    const app=getApp();
    console.log(app.globalData);
    console.log(app);
  }
});

结果

3.3、page注册与生命周期

对于小程序中的每个页面,都需要在页面对应的 js 文件中进行注册,指定页面的初始数据、生命周期回调、事件处理函数等。

onlaunch:当小程序初始化完成时,会触发 onLaunch(全局只触发一次)(app.js);
onLoad: 页面加载小程序注册完成后,加载页面,触发onLoad方法。一个页面只会调用一次,可以在 onLoad 中获取打开当前页面所调用的 query 参数(页面js)。
onShow: 页面显示页面载入后触发onShow方法,显示页面。每次打开页面都会调用一次(比如当小程序有后台进入到前台运行或重新进入页面时)。
onReady: 首次显示页面,页面初次渲染完成,会触发onReady方法,渲染页面元素和样式,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。对界面的设置如wx.setNavigationBarTitle请在onReady之后设置。
onHide: 页面隐藏当navigateTo、底部tab切换、上传文件选择图片时调用。
onUnload: 页面卸载当返回上一页wx.navigateBack、wx.relanch、wx.redirectTo时都会被调用

3.3.1、使用 Page 构造器注册页面

简单的页面可以使用 Page() 进行构造。

代码示例:

//index.js
Page({
  data: {
    text: "This is page data."
  },
  onLoad: function(options) {
    // 页面创建时执行
  },
  onShow: function() {
    // 页面出现在前台时执行
  },
  onReady: function() {
    // 页面首次渲染完毕时执行
  },
  onHide: function() {
    // 页面从前台变为后台时执行
  },
  onUnload: function() {
    // 页面销毁时执行
  },
  onPullDownRefresh: function() {
    // 触发下拉刷新时执行
  //json文件中enablePullDownRefresh:true开启下拉刷新
//wx.stopPullDownRefresh(); 数据更新完成后,调用该方法停止刷新
}, onReachBottom: function() { // 页面触底时执行
  //onReachBottomDistance }, onShareAppMessage: function () { // 页面被用户分享时执行 }, onPageScroll: function(options) { // 页面滚动时执行
  //scrollTop 距离 }, onResize: function() { // 页面尺寸变化时执行 }, onTabItemTap(item) { // tab 点击时执行 console.log(item.index) console.log(item.pagePath) console.log(item.text) }, // 事件响应函数 viewTap: function() { this.setData({ text: 'Set some data for updating view.' }, function() { // this is setData callback }) }, // 自由数据 customData: { hi: 'MINA' } })

详细的参数含义和使用请参考 Page 参考文档 。

3.3.2、page.onLoad

onLoad(Object query)

页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。

hello/index.js

//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  }
});

logs/logs

Page({
  goPage(){
    wx.navigateTo({
      url: '../hello/index?k1=v1&a=100&b=200',
    })
  }
})

结果

3.3.3、page.onShow

https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html

页面显示/切入前台时触发。会反复执行

pages/hello/index

//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  },
  onShow(options){
    console.log("Page->onShow:页面显示",options);
  }
});

 

3.3.4、page.onReady

页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。

注意:对界面内容进行设置的 API 如wx.setNavigationBarTitle,请在onReady之后进行。详见生命周期

//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  },
  onShow(options){
    console.log("Page->onShow:页面显示",options);
  },
  onReady(options){
    console.log("Page->onReady:页面准备完成",options);
  },
});

 

 从上面的截图可以看出,onReady与onShow都没有参数,onReady只会执行1次,如果页面实例没有被销毁重新创建时则只会执行一次。

3.3.5、page.onHide()

页面隐藏/切入后台时触发。 如 wx.navigateTo 或底部 tab 切换到其他页面,小程序切入后台等。

//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  },
  onShow(options){
    console.log("Page->onShow:页面显示",options);
  },
  onReady(options){
    console.log("Page->onReady:页面准备完成",options);
  },
  onHide(options){
    console.log("Page->onHide:页面切入后台/隐藏",options);
  },
});

3.3.6、page.onUnload

页面卸载时触发。如wx.redirectTowx.navigateBack到其他页面时。

//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  redictHandle(e){
    wx.redirectTo({
      url: '../hi/index',
    })
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  },
  onShow(options){
    console.log("Page->onShow:页面显示",options);
  },
  onReady(options){
    console.log("Page->onReady:页面准备完成",options);
  },
  onHide(options){
    console.log("Page->onHide:页面切入后台/隐藏",options);
  },
  onUnload(options){
    console.log("Page->onUnload:页面准备卸载",options);
  }
});

 3.3.7、page.onPullDownRefresh

监听用户下拉刷新事件。

  • 需要在app.jsonwindow选项中或页面配置中开启enablePullDownRefresh
  • 可以通过wx.startPullDownRefresh触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
  • 当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。

修改pages/hello/index.json

{
  "usingComponents": {},
  "navigationBarBackgroundColor": "#0f0",
  "navigationBarTitleText": "问候页",
  "navigationBarTextStyle": "black",
  "enablePullDownRefresh": true
}
//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  redictHandle(e){
    wx.redirectTo({
      url: '../hi/index',
    })
  },
  pullDownRefreshHandle(e){
    //开始下拉刷新,没有下拉效果
    wx.startPullDownRefresh();
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  },
  onShow(options){
    console.log("Page->onShow:页面显示",options);
  },
  onReady(options){
    console.log("Page->onReady:页面准备完成",options);
  },
  onHide(options){
    console.log("Page->onHide:页面切入后台/隐藏",options);
  },
  onUnload(options){
    console.log("Page->onUnload:页面准备卸载",options);
  },
  onPullDownRefresh(options){
    console.log("Page->onPullDownRefresh:下拉刷新",options);
    //如果不及时停止下拉刷新则会过一会才会收起刷新
    wx.stopPullDownRefresh();
  }
});

3.3.8、page.onReachBottom

监听用户上拉触底事件。

  • 可以在app.jsonwindow选项中或页面配置中设置触发距离onReachBottomDistance
  • 在触发距离内滑动期间,本事件只会被触发一次。
//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  redictHandle(e){
    wx.redirectTo({
      url: '../hi/index',
    })
  },
  pullDownRefreshHandle(e){
    //开始下拉刷新,没有下拉效果
    wx.startPullDownRefresh();
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  },
  onShow(options){
    console.log("Page->onShow:页面显示",options);
  },
  onReady(options){
    console.log("Page->onReady:页面准备完成",options);
  },
  onHide(options){
    console.log("Page->onHide:页面切入后台/隐藏",options);
  },
  onUnload(options){
    console.log("Page->onUnload:页面准备卸载",options);
  },
  onPullDownRefresh(options){
    console.log("Page->onPullDownRefresh:下拉刷新",options);
    //如果不及时停止下拉刷新则会过一会才会收起刷新
    wx.stopPullDownRefresh();
  },
  onReachBottom(options){
    console.log("Page->onReachBottom:上拉触底事件",options);
  }
});

index.json

{
  "usingComponents": {},
  "navigationBarBackgroundColor": "#0f0",
  "navigationBarTitleText": "问候页",
  "navigationBarTextStyle": "black",
  "enablePullDownRefresh": true,
  "onReachBottomDistance": 200
}

运行效果

3.3.9、page.onShareAppMessage

https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onShareAppMessage-Object-object

监听用户点击页面内转发按钮(button 组件 open-type="share")或右上角菜单“转发”按钮的行为,并自定义转发内容。

注意:只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮

参数 Object object:

参数类型说明最低版本
from String 转发事件来源。
button:页面内转发按钮;
menu:右上角转发菜单
1.2.4
target Object 如果 from 值是 button,则 target 是触发这次转发事件的 button,否则为 undefined 1.2.4
webViewUrl String 页面中包含web-view组件时,返回当前web-view的url 1.6.4

此事件处理函数需要 return 一个 Object,用于自定义转发内容,返回内容如下:

自定义转发内容 基础库 2.8.1 起,分享图支持云图片。

字段说明默认值最低版本
title 转发标题 当前小程序名称  
path 转发路径 当前页面 path ,必须是以 / 开头的完整路径  
imageUrl 自定义图片路径,可以是本地文件路径、代码包文件路径或者网络图片路径。支持PNG及JPG。显示图片长宽比是 5:4。 使用默认截图 1.5.0
promise 如果该参数存在,则以 resolve 结果为准,如果三秒内不 resolve,分享会使用上面传入的默认参数   2.12.0

示例代码

在开发者工具中预览效果

Page({
  onShareAppMessage() {
    const promise = new Promise(resolve => {
      setTimeout(() => {
        resolve({
          title: '自定义转发标题'
        })
      }, 2000)
    })
    return {
      title: '自定义转发标题',
      path: '/page/user?id=123',
      promise 
    }
  }
})
//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  redictHandle(e){
    wx.redirectTo({
      url: '../hi/index',
    })
  },
  pullDownRefreshHandle(e){
    //开始下拉刷新,没有下拉效果
    wx.startPullDownRefresh();
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  },
  onShow(options){
    console.log("Page->onShow:页面显示",options);
  },
  onReady(options){
    console.log("Page->onReady:页面准备完成",options);
  },
  onHide(options){
    console.log("Page->onHide:页面切入后台/隐藏",options);
  },
  onUnload(options){
    console.log("Page->onUnload:页面准备卸载",options);
  },
  onPullDownRefresh(options){
    console.log("Page->onPullDownRefresh:下拉刷新",options);
    //如果不及时停止下拉刷新则会过一会才会收起刷新
    wx.stopPullDownRefresh();
  },
  onReachBottom(options){
    console.log("Page->onReachBottom:上拉触底事件",options);
  },
  onShareAppMessage(options){
    console.log("Page->onShareAppMessage:分享事件",options);

    const promise = new Promise(resolve => {
      setTimeout(() => {
        resolve({
          title: '自定义转发标题A'
        })
      }, 2000)
    })
    return {
      title: '自定义转发标题B',
      path: '/hello/index?id=123',
      promise 
    }
  }
});

index.wxml

<view>
<button type="primary" bindtap="countHandle">{{count}}</button>
</view>

<view>
  <button type="primary" bindtap="redictHandle">重定向</button>
</view>

<view>
  <button type="primary" bindtap="pullDownRefreshHandle">触发下拉刷新</button>
</view>

<view>
  <button open-type="share" type="primary">分享</button>
</view>

<view class="m"></view>

运行效果

 3.3.10、page.onPageScroll

监听用户滑动页面事件。

参数 Object object:

属性类型说明
scrollTop Number 页面在垂直方向已滚动的距离(单位px)

注意:请只在需要的时候才在 page 中定义此方法,不要定义空方法。以减少不必要的事件派发对渲染层-逻辑层通信的影响。 注意:请避免在 onPageScroll 中过于频繁的执行 setData 等引起逻辑层-渲染层通信的操作。尤其是每次传输大量数据,会影响通信耗时。

//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  redictHandle(e){
    wx.redirectTo({
      url: '../hi/index',
    })
  },
  pullDownRefreshHandle(e){
    //开始下拉刷新,没有下拉效果
    wx.startPullDownRefresh();
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  },
  onShow(options){
    console.log("Page->onShow:页面显示",options);
  },
  onReady(options){
    console.log("Page->onReady:页面准备完成",options);
  },
  onHide(options){
    console.log("Page->onHide:页面切入后台/隐藏",options);
  },
  onUnload(options){
    console.log("Page->onUnload:页面准备卸载",options);
  },
  onPullDownRefresh(options){
    console.log("Page->onPullDownRefresh:下拉刷新",options);
    //如果不及时停止下拉刷新则会过一会才会收起刷新
    wx.stopPullDownRefresh();
  },
  onReachBottom(options){
    console.log("Page->onReachBottom:上拉触底事件",options);
  },
  onShareAppMessage(options){
    console.log("Page->onShareAppMessage:分享事件",options);

    const promise = new Promise(resolve => {
      setTimeout(() => {
        resolve({
          title: '自定义转发标题A'
        })
      }, 2000)
    })
    return {
      title: '自定义转发标题B',
      path: '/hello/index?id=123',
      promise 
    }
  },
  onPageScroll(options){
    console.log("Page->onPageScroll:滚动事件",options);
  }
});

 3.3.11、page.onResize

小程序屏幕旋转时触发。详见 响应显示区域变化

显示区域尺寸

显示区域指小程序界面中可以自由布局展示的区域。在默认情况下,小程序显示区域的尺寸自页面初始化起就不会发生变化。但以下两种方式都可以改变这一默认行为。

在手机上启用屏幕旋转支持

从小程序基础库版本 2.4.0 开始,小程序在手机上支持屏幕旋转。使小程序中的页面支持屏幕旋转的方法是:在 app.json 的 window 段中设置 "pageOrientation": "auto" ,或在页面 json 文件中配置 "pageOrientation": "auto" 。

{
  "usingComponents": {},
  "navigationBarBackgroundColor": "#0f0",
  "navigationBarTitleText": "问候页",
  "navigationBarTextStyle": "black",
  "enablePullDownRefresh": true,
  "onReachBottomDistance": 200,
  "pageOrientation": "auto"
}

hello/index.js

//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  redictHandle(e){
    wx.redirectTo({
      url: '../hi/index',
    })
  },
  pullDownRefreshHandle(e){
    //开始下拉刷新,没有下拉效果
    wx.startPullDownRefresh();
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  },
  onShow(options){
    console.log("Page->onShow:页面显示",options);
  },
  onReady(options){
    console.log("Page->onReady:页面准备完成",options);
  },
  onHide(options){
    console.log("Page->onHide:页面切入后台/隐藏",options);
  },
  onUnload(options){
    console.log("Page->onUnload:页面准备卸载",options);
  },
  onPullDownRefresh(options){
    console.log("Page->onPullDownRefresh:下拉刷新",options);
    //如果不及时停止下拉刷新则会过一会才会收起刷新
    wx.stopPullDownRefresh();
  },
  onReachBottom(options){
    console.log("Page->onReachBottom:上拉触底事件",options);
  },
  onShareAppMessage(options){
    console.log("Page->onShareAppMessage:分享事件",options);

    const promise = new Promise(resolve => {
      setTimeout(() => {
        resolve({
          title: '自定义转发标题A'
        })
      }, 2000)
    })
    return {
      title: '自定义转发标题B',
      path: '/hello/index?id=123',
      promise 
    }
  },
  onPageScroll(options){
    console.log("Page->onPageScroll:滚动事件",options);
  },
  onResize(options){
    console.log("Page->onResize:旋转屏幕",options);
  }
});

3.3.12、page.onTabItemTap

点击 tab 时触发

Object 参数说明:

参数类型说明最低版本
index String 被点击tabItem的序号,从0开始 1.9.0
pagePath String 被点击tabItem的页面路径 1.9.0
text String 被点击tabItem的按钮文字 1.9.0
//注册页面
Page({
  data:{
    count:100
  },
  countHandle(e){
    this.setData({count:this.data.count+1})
  },
  redictHandle(e){
    wx.redirectTo({
      url: '../hi/index',
    })
  },
  pullDownRefreshHandle(e){
    //开始下拉刷新,没有下拉效果
    wx.startPullDownRefresh();
  },
  onLoad(query){
    console.log("Page->onLoad:页面加载成功",query)
  },
  onShow(options){
    console.log("Page->onShow:页面显示",options);
  },
  onReady(options){
    console.log("Page->onReady:页面准备完成",options);
  },
  onHide(options){
    console.log("Page->onHide:页面切入后台/隐藏",options);
  },
  onUnload(options){
    console.log("Page->onUnload:页面准备卸载",options);
  },
  onPullDownRefresh(options){
    console.log("Page->onPullDownRefresh:下拉刷新",options);
    //如果不及时停止下拉刷新则会过一会才会收起刷新
    wx.stopPullDownRefresh();
  },
  onReachBottom(options){
    console.log("Page->onReachBottom:上拉触底事件",options);
  },
  onShareAppMessage(options){
    console.log("Page->onShareAppMessage:分享事件",options);

    const promise = new Promise(resolve => {
      setTimeout(() => {
        resolve({
          title: '自定义转发标题A'
        })
      }, 2000)
    })
    return {
      title: '自定义转发标题B',
      path: '/hello/index?id=123',
      promise 
    }
  },
  onPageScroll(options){
    console.log("Page->onPageScroll:滚动事件",options);
  },
  onResize(options){
    console.log("Page->onResize:旋转屏幕",options);
  },
  onTabItemTap(options){
    console.log("Page->onTabItemTap:切换选项卡",options);
  }
});

3.3.13、在页面中使用 behaviors

基础库 2.9.2 开始支持,低版本需做兼容处理

页面可以引用 behaviors 。 behaviors 可以用来让多个页面有相同的数据字段和方法。

// my-behavior.js
module.exports = Behavior({
  data: {
    sharedText: 'This is a piece of data shared between pages.'
  },
  methods: {
    sharedMethod: function() {
      this.data.sharedText === 'This is a piece of data shared between pages.'
    }
  }
})
// page-a.js
var myBehavior = require('./my-behavior.js')
Page({
  behaviors: [myBehavior],
  onLoad: function() {
    this.data.sharedText === 'This is a piece of data shared between pages.'
  }
})

具体用法参见 behaviors 。

在pages下面定义countBehavior.js文件,共享部分:

module.exports=Behavior({
  data:{
    count:999
  },
  methods:{
    countHandler(e){
      this.setData({count:this.data.count+1});
    }
  }
})

hello/index.js文件

const countBehavior=require("../countBehavior");
Page({
  behaviors:[countBehavior]
})

hello/index.wxml

<view>
  <button type="primary" bindtap="countHandler">{{count}}</button>
</view>

运行效果

 logs/logs.js

const countBehavior=require("../countBehavior");
Page({
  behaviors:[countBehavior]
})

logs/logs.wxml

<view>
  <button type="primary" bindtap="countHandler">{{count}}</button>
</view>

运行效果

 生命周期函数一样可以复用

behaviors 是用于组件间代码共享的特性,类似于一些编程语言中的 “mixins” 或 “traits”。

每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。 每个组件可以引用多个 behavior ,behavior 也可以引用其它 behavior 。

详细的参数含义和使用请参考 Behavior 参考文档

组件中使用

组件引用时,在 behaviors 定义段中将它们逐个列出即可。

代码示例:

在开发者工具中预览效果

// my-component.js
var myBehavior = require('my-behavior')
Component({
  behaviors: [myBehavior],
  properties: {
    myProperty: {
      type: String
    }
  },
  data: {
    myData: 'my-component-data'
  },
  created: function () {
    console.log('[my-component] created')
  },
  attached: function () { 
    console.log('[my-component] attached')
  },
  ready: function () {
    console.log('[my-component] ready')
  },
  methods: {
    myMethod: function () {
      console.log('[my-component] log by myMethod')
    },
  }
})

在上例中, my-component 组件定义中加入了 my-behavior

而 my-behavior 结构为:

  • 属性:myBehaviorProperty
  • 数据字段:myBehaviorData
  • 方法:myBehaviorMethod
  • 生命周期函数:attachedcreatedready

这将使 my-component 最终结构为:

  • 属性:myBehaviorPropertymyProperty
  • 数据字段:myBehaviorDatamyData
  • 方法:myBehaviorMethodmyMethod
  • 生命周期函数:attachedcreatedready

当组件触发生命周期时,上例生命周期函数执行顺序为:

  1. [my-behavior] created
  2. [my-component] created
  3. [my-behavior] attached
  4. [my-component] attached
  5. [my-behavior] ready
  6. [my-component] ready

详细规则参考 同名字段的覆盖和组合规则

同名字段的覆盖和组合规则

组件和它引用的 behavior 中可以包含同名的字段,对这些字段的处理方法如下:

  • 如果有同名的属性 (properties) 或方法 (methods):
    1. 若组件本身有这个属性或方法,则组件的属性或方法会覆盖 behavior 中的同名属性或方法;
    2. 若组件本身无这个属性或方法,则在组件的 behaviors 字段中定义靠后的 behavior 的属性或方法会覆盖靠前的同名属性或方法;
    3. 在 2 的基础上,若存在嵌套引用 behavior 的情况,则规则为:引用者 behavior 覆盖 被引用的 behavior 中的同名属性或方法。
  • 如果有同名的数据字段 (data):
    • 若同名的数据字段都是对象类型,会进行对象合并;
    • 其余情况会进行数据覆盖,覆盖规则为: 引用者 behavior > 被引用的 behavior 、 靠后的 behavior > 靠前的 behavior。(优先级高的覆盖优先级低的,最大的为优先级最高)
  • 生命周期函数和 observers 不会相互覆盖,而是在对应触发时机被逐个调用:
    • 对于不同的生命周期函数之间,遵循组件生命周期函数的执行顺序;
    • 对于同种生命周期函数和同字段 observers ,遵循如下规则:
      • behavior 优先于组件执行;
      • 被引用的 behavior 优先于 引用者 behavior 执行;
      • 靠前的 behavior 优先于 靠后的 behavior 执行;
    • 如果同一个 behavior 被一个组件多次引用,它定义的生命周期函数和 observers 不会重复执行。

代码示例:

在开发者工具中预览效果

内置 behaviors

自定义组件可以通过引用内置的 behavior 来获得内置组件的一些行为。

Component({
  behaviors: ['wx://form-field']
})

在上例中, wx://form-field 代表一个内置 behavior ,它使得这个自定义组件有类似于表单控件的行为。

内置 behavior 往往会为组件添加一些属性。在没有特殊说明时,组件可以覆盖这些属性来改变它的 type 或添加 observer 。

wx://form-field

使自定义组件有类似于表单控件的行为。 form 组件可以识别这些自定义组件,并在 submit 事件中返回组件的字段名及其对应字段值。

详细用法以及代码示例可见:form 组件参考文档

wx://form-field-group

从基础库版本 2.10.2 开始提供支持。

使 form 组件可以识别到这个自定义组件内部的所有表单控件。

详细用法以及代码示例可见:form 组件参考文档

wx://form-field-button

从基础库版本 2.10.3 开始提供支持。

使 form 组件可以识别到这个自定义组件内部的 button 。如果自定义组件内部有设置了 form-type 的 button ,它将被组件外的 form 接受。

详细用法以及代码示例可见:form 组件参考文档

wx://component-export

从基础库版本 2.2.3 开始提供支持。

使自定义组件支持 export 定义段。这个定义段可以用于指定组件被 selectComponent 调用时的返回值。

详细用法以及代码示例可见:selectComponent 参考文档

 

 

 

 

onLoad(Object query)

页面加载时触发,一个页面只会调用一次,可以在onLoad的参数中获取打开当前页面路径中的参数,一般建议在这个函数中做一些数据初始化的工作。

onShow()

页面显示/切入前台时触发,比如:新推入了一个新的页面,那么原来的页面就处于后台,这时如果把新页面又移除掉,那么下面的页面就会调用onShow方法

onReady()

页面初次渲染完成时触发,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互,对界面内容进行设置的API,可以在这个页面中进行执行

onHide()

页面隐藏/切入后台时触发,如:navigateTo或底部tab切换至其他页面,小程序切入后台等

onUnload()

页面卸载时触发,如:redirectTo或navigateBack到其他页面

3.4、总结

1. 打开小程序:

(App)onLaunch --> (App)onShow --> (Pages)onLoad --> (Pages)onShow --> (pages)onReady

2. 进入下一个页面:

(Pages)onHide --> (Next)onLoad --> (Next)onShow --> (Next)onReady

3. 返回上一个页面:

(curr)onUnload --> (pre)onShow

4. 离开小程序:

(App)onHide

5. 再次进入:

小程序未销毁 --> (App)onShow(执行上面的顺序),小程序被销毁,(App)onLaunch重新开始执行.

四、视频

【微信小程序开发】 https://www.bilibili.com/video/BV1pv4y1n7Zg/?share_source=copy_web&vd_source=475a31f3c5d6353a782007cd4c638a8a

五、作业

posted @ 2023-04-27 08:33  张果  阅读(2173)  评论(0编辑  收藏  举报
AmazingCounters.com