微信小程序
- 微信小程序
- 1.微信小程序介绍
- 2.配置环境
- 3.微信开发者工具介绍
- 4. 小程序结构目录
- 4.1 小程序文件结构和传统 web 对比
- 4.2. 基本的项目 目录
- 4.3 [sitemap.json 文件](https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html)
- 5. 小程序配置文件
- 5.1. [全局配置 app.json](https://developers.weixin.qq.com/miniprogram/dev/framework/config.html)
- 5.1.1 [pages](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#pages)
- 5.1.2 [window](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#window)
- 5.1.3 [tabBar](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#tabBar)
- 5.2 [页面配置](https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#%E9%A1%B5%E9%9D%A2%E9%85%8D%E7%BD%AE)
- 6. 模板语法
- 7. 案例展示
- 8. Mock.js
- 8.1 在线编辑器
- 8.2 下载
- 8.3 语法规范
- 8.3.1 数据模板定义 DTD
- 8.3.2 数据占位符定义 DPD
- 8.3.3 Mock.Random
- 8.3.3.1 Basics
- 8.3.3.1.1 Random.boolean(min, max, cur)
- 8.3.3.1.2 Random.natural(min, max)
- 8.3.3.1.3 Random.integer(min, max)
- 8.3.3.1.4 Random.float(min, max, dmin, dmax)
- 8.3.3.1.5 Random.character(pool)
- 8.3.3.1.6 Random.string(pool, min, max)
- 8.3.3.1.7 Random.range(start, stop, step)
- 8.3.3.1.8 Random.date(format)
- 8.3.3.1.9 Random.time(format)
- 8.3.3.1.10 Random.datetime(format)
- 8.3.3.1.11 Random.now(unit, format)
- 8.3.3.4 Image
- 8.3.3.5 Color
- 8.3.3.6 Text
- 8.3.3.7 Name
微信小程序
1.微信小程序介绍
微信小程序,简称小程序,英⽂名 Mini Program ,是⼀种不需要下载安装即可使⽤的应⽤,它实现 了应用“触⼿可及”的梦想,用户扫⼀扫或搜⼀下即可打开应用
1.1. 为什么是微信小程序 ?
- 微信有海量用户,而且粘性很⾼,在微信⾥开发产品更容易触达用户;
- 推广 app 或公众号的成本太⾼。
- 开发适配成本低。
- 容易小规模试错,然后快速迭代。
- 跨平台。
1.2. 微信小程序历史
-
2016年1⽉11⽇,微信之父张小龙时隔多年的公开亮相,解读了微信的四⼤价值观。张小龙指出, 越来越多产品通过公众号来做,因为这⾥开发、获取用户和传播成本更低。拆分出来的服务号并没 有提供更好的服务,所以微信内部正在研究新的形态,叫「微信小程序」 需要注意的是,之前是叫 做 应⽤号
-
2016年9⽉21⽇,微信小程序正式开启内测。在微信生态下,触⼿可及、用完即⾛的微信小程序引 起⼴泛关注。腾讯云正式上线微信小程序解决⽅案,提供小程序在云端服务器的技术⽅案。
-
2017年1⽉9⽇,微信推出的“小程序”正式上线。“小程序”是⼀种⽆需安装,即可使⽤的手机“应用”。不需要像往常⼀样下载App,⽤⼾在微信中“用完即走”。
1.3. 疯狂的微信小程序
- 微信月活已经达到10.82亿。其中55岁以上的用户也达到6300万
- 信息传达数达到450亿,较去年增长18%;视频通话4.1亿次,增⻓100%
- 小程序覆盖超过200+行业,交易额增长超过6倍,服务1000亿+⼈次,创造出了5000亿+的商业价值
1.4. 还有其他的小程序 不容忽视
- ⽀付宝小程序
- 百度小程序
- QQ小程序
- 今⽇头条 + 抖⾳小程序
1.5. 体验
1.5.1. 官方微信小程序体验
1.5.2. 其他优秀的第三方小程序
- 拼多多
- 滴滴出行
- 欢乐斗地主
- 智行火车票
- 唯品会
- 。。。
2.配置环境
开发微信⼩程序之前,必须要准备好相应的环境
2.1.注册账号
建议使用全新的邮箱,没有注册过其他小程序或者公众号的。访问 注册页面 耐心完成注册即可
2.2.获取AppID
由于后期调⽤微信⼩程序的接⼝等功能,需要索取开发者的小程序中的 APPID ,所以在注册成功后, 可登录 微信公众平台,然后获取APPID。
登录成功后,可以按照以下操作获取你的AppID,然后复制保存,粘贴到你的AppID位置
2.3.下载开发工具并配置开发环境
2.3.1下载开发者工具
2.3.2配置一下环境
2.3.2.1打开微信开发者工具
注意:第一次登录时,需要微信扫码登录
在登录时,最常遇到网络连接失败问题,如图所示:
这种问题是由于手机和电脑的网络匹配失败的问题
解决这个问题的方法为:
-
电脑和手机直接用同一个WiFi
-
电脑使用网线,打开移动网络,让手机脸上电脑的热点
如图所示:
2.3.2.1 新建小程序项目
第一步:
第二步:
第三步:再设置设置好之后点击创建之后,就可以打开此页面
注意:你可以通过设置改变编译器的外观样式
这里面的模拟器就是上一图的预览区
微信⼩程序⾃带开发者⼯具,集 开发 预览 调试 发布 于⼀⾝的 完整环境。 但是由于编码的体验不算好,因此 建议使⽤ vs code
+ 微信小程序编辑工具
来实现编码 vs code
负责敲代码, 微信编辑工具
负责预览
3.微信开发者工具介绍
详细的使⽤,可以查看官网
4. 小程序结构目录
小程序框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。
小程序框架提供了⾃⼰的视图层描述语⾔ WXML
和 WXSS
,以及 JavaScript
,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。
4.1 小程序文件结构和传统 web 对比
结构 | 传统web | 微信小程序 |
---|---|---|
结构 | HTML | WXML |
样式 | CSS | WXSS |
逻辑 | JavaScript | JavaScript |
配置 | 无 | JSON |
通过以上对比得出,传统web 是三层结构。⽽微信小程序 是四层结构,多了⼀层 配置.json
4.1.1 WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
要完整了解 WXML 语法,请参考WXML 语法参考。
详细讲解我们回在模板语法中讲到
4.1.2 WXSS
WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
WXSS 用来决定 WXML 的组件应该怎么显示。
为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。
与 CSS 相比,WXSS 扩展的特性有:
- 尺寸单位
- 样式导入
4.1.2.1 尺寸单位
微信小程序中使用 rpx 作为单位
- 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 作为视觉稿的标准。
注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。
把握一个原则
设计师基于 iphone6 出设计稿,设计稿尺寸一般就是 750*1344(2倍),我们直接使用元素中标注 或者测量的尺寸即可,只需要将单位设置为 rpx
使⽤步骤:
- 确定设计稿宽度 pageWidth
- 计算比例 750rpx = pageWidth px ,因此 1px=750rpx/pageWidth
- 在less文件中,只要把设计稿中的 px => 750/pageWidth rpx 即可
4.1.2.2 样式导入
wxss中直接就⽀持,样式导⼊功能。
也可以和 less中的导⼊混⽤。
使用@import
语句可以导入外联样式表,@import
后跟需要导入的外联样式表的相对路径,用;
表示语句结束。
示例代码:
/** common.wxss **/
.small-p {
padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {
padding:15px;
}
4.1.2.3 内联样式
框架组件上支持使用 style、class 属性来控制组件的样式。
- style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。
<view style="color:{{color}};" />
- class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上
.
,样式类名之间用空格分隔。
<view class="normal_view" />
4.1.2.4 选择器
WXSS 仅支持部分 CSS 选择器
目前支持的选择器有:
选择器 | 样例 | 样例描述 |
---|---|---|
.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 组件前边插入内容 |
4.1.2.5 全局样式与局部样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。
在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。
4.1.3 WXS
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML
,可以构建出页面的结构。
4.1.3.1 注意
- WXS 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。
- WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。
- WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API。
- WXS 函数不能作为组件的事件回调。
- 由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。
4.1.3.2 页面渲染
<!--wxml-->
<wxs module="m1">
var msg = "hello world";
module.exports.message = msg;
</wxs>
<view> {{m1.message}} </view>
页面输出:
hello world
4.1.3.3 数据处理
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5, 1, 2, 3, 4]
}
})
<!--wxml-->
<!-- 下面的 getMax 函数,接受一个数组,且返回数组中最大的元素的值 -->
<wxs module="m1">
var getMax = function(array) {
var max = undefined;
for (var i = 0; i < array.length; ++i) {
max = max === undefined ?
array[i] :
(max >= array[i] ? max : array[i]);
}
return max;
}
module.exports.getMax = getMax;
</wxs>
<!-- 调用 wxs 里面的 getMax 函数,参数为 page.js 里面的 array -->
<view> {{m1.getMax(array)}} </view>
页面输出:
5
4.1.3.4 语法
4.1.3.4.1 WXS 模块
WXS 代码可以编写在 wxml 文件中的 <wxs>
标签内,或以 .wxs
为后缀名的文件内。
模块
每一个 .wxs
文件和 <wxs>
标签都是一个单独的模块。
每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。
一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports
实现。
4.1.3.4.2 变量
- WXS 中的变量均为值的引用。
- 没有声明的变量直接赋值使用,会被定义为全局变量。
- 如果只声明变量而不赋值,则默认值为
undefined
。 - var表现与javascript一致,会有变量提升。
var foo = 1;
var bar = "hello world";
var i; // i === undefined
上面代码,分别声明了 foo
、 bar
、 i
三个变量。然后,foo
赋值为数值 1
,bar
赋值为字符串 "hello world"
。
变量名
变量命名必须符合下面两个规则:
- 首字符必须是:字母(a-zA-Z),下划线(_)
- 剩余字符可以是:字母(a-zA-Z),下划线(_), 数字(0-9)
保留标识符
以下标识符不能作为变量名:
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
4.1.3.4.3 WXS 主要有 3 种注释的方法。
示例代码:
<!-- wxml -->
<wxs module="sample">
// 方法一:单行注释
/*
方法二:多行注释
*/
/*
方法三:结尾注释。即从 /* 开始往后的所有 WXS 代码均被注释
var a = 1;
var b = 2;
var c = "fake";
</wxs>
上述例子中,所有 WXS 代码均被注释掉了。
方法三 和 方法二 的唯一区别是,没有
*/
结束符。
4.1.3.4.4 运算符
基本运算符
示例代码:
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);
一元运算符
示例代码:
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);
位运算符
示例代码:
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));
比较运算符
示例代码:
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));
等值运算符
示例代码:
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));
赋值运算符
示例代码:
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);
二元逻辑运算符
示例代码:
var a = 10, b = 20;
// 逻辑与
console.log(20 === (a && b));
// 逻辑或
console.log(10 === (a || b));
其他运算符
示例代码:
var a = 10, b = 20;
//条件运算符
console.log(20 === (a >= 10 ? a + 10 : b + 10));
//逗号运算符
console.log(20 === (a, b));
运算符优先级
优先级 | 运算符 | 说明 | 结合性 |
---|---|---|---|
20 | ( … ) | 括号 | n/a |
19 | … . … | 成员访问 | 从左到右 |
… [ … ] | 成员访问 | 从左到右 | |
… ( … ) | 函数调用 | 从左到右 | |
17 | … ++ | 后置递增 | n/a |
… -- | 后置递减 | n/a | |
16 | ! … | 逻辑非 | 从右到左 |
~ … | 按位非 | 从右到左 | |
+ … | 一元加法 | 从右到左 | |
- … | 一元减法 | 从右到左 | |
++ … | 前置递增 | 从右到左 | |
-- … | 前置递减 | 从右到左 | |
typeof … | typeof | 从右到左 | |
void … | void | 从右到左 | |
delete … | delete | 从右到左 | |
14 | … * … | 乘法 | 从左到右 |
… / … | 除法 | 从左到右 | |
… % … | 取模 | 从左到右 | |
13 | … + … | 加法 | 从左到右 |
… - … | 减法 | 从左到右 | |
12 | … << … | 按位左移 | 从左到右 |
… >> … | 按位右移 | 从左到右 | |
… >>> … | 无符号右移 | 从左到右 | |
11 | … < … | 小于 | 从左到右 |
… <= … | 小于等于 | 从左到右 | |
… > … | 大于 | 从左到右 | |
… >= … | 大于等于 | 从左到右 | |
10 | … == … | 等号 | 从左到右 |
… != … | 非等号 | 从左到右 | |
… === … | 全等号 | 从左到右 | |
… !== … | 非全等号 | 从左到右 | |
9 | … & … | 按位与 | 从左到右 |
8 | … ^ … | 按位异或 | 从左到右 |
7 | … | … | 按位或 | 从左到右 |
6 | … && … | 逻辑与 | 从左到右 |
5 | … || … | 逻辑或 | 从左到右 |
4 | … ? … : … | 条件运算符 | 从右到左 |
3 | … = … | 赋值 | 从右到左 |
… += … | 赋值 | 从右到左 | |
… -= … | 赋值 | 从右到左 | |
… *= … | 赋值 | 从右到左 | |
… /= … | 赋值 | 从右到左 | |
… %= … | 赋值 | 从右到左 | |
… <<= … | 赋值 | 从右到左 | |
… >>= … | 赋值 | 从右到左 | |
… >>>= … | 赋值 | 从右到左 | |
… &= … | 赋值 | 从右到左 | |
… ^= … | 赋值 | 从右到左 | |
… |= … | 赋值 | 从右到左 | |
0 | … , … | 逗号 | 从左到右 |
4.1.3.6 语句
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 {
代码块;
}
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
for 语句
示例语法:
for (语句; 语句; 语句)
语句;
for (语句; 语句; 语句) {
代码块;
}
- 支持使用
break
,continue
关键词。
示例代码:
for (var i = 0; i < 3; ++i) {
console.log(i);
if( i >= 1) break;
}
输出:
0
1
while 语句
示例语法:
while (表达式)
语句;
while (表达式){
代码块;
}
do {
代码块;
} while (表达式)
- 当
表达式
为 true 时,循环执行语句
或代码块
。 - 支持使用
break
,continue
关键词。
4.1.3.6 数据类型
WXS 语言目前共有以下几种数据类型:
number
: 数值string
:字符串boolean
:布尔值object
:对象function
:函数array
: 数组date
:日期regexp
:正则
4.1.3.7 基础类库
console
console.log
方法用于在 console 窗口输出信息。它可以接受多个参数,将它们的结果连接起来输出。
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
标准。
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(){})));
Number
属性
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
POSITIVE_INFINITY
以上属性的具体使用请参考
ES5
标准。
Date
属性
parse
UTC
now
以上属性的具体使用请参考
ES5
标准。
Global
属性
NaN
Infinity
undefined
以上属性的具体使用请参考
ES5
标准。
方法
parseInt
parseFloat
isNaN
isFinite
decodeURI
decodeURIComponent
encodeURI
encodeURIComponent
以上方法的具体使用请参考
ES5
标准。
4.2. 基本的项目 目录
4.3 sitemap.json 文件
微信现已开放小程序内搜索,开发者可以通过 sitemap.json
配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中。 爬虫访问小程序内页面时,会携带特定的 user-agent:mpcrawler
及场景值:1129
。需要注意的是,若小程序爬虫发现的页面数据和真实用户的呈现不一致,那么该页面将不会进入索引中。
具体配置说明
- 页面收录设置:可对整个小程序的索引进行关闭,小程序管理后台-功能-页面内容接入-页面收录开关;详情
- sitemap 配置:可对特定页面的索引进行关闭
4.3.1 sitemap 配置
微信现已开放小程序内搜索,开发者可以通过 sitemap.json
配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中。 爬虫访问小程序内页面时,会携带特定的 user-agent:mpcrawler
及场景值:1129
。需要注意的是,若小程序爬虫发现的页面数据和真实用户的呈现不一致,那么该页面将不会进入索引中。
总之一句话:小程序根目录下的 sitemap.json
文件用来配置小程序及其页面是否允许被微信索引。
文件内容为一个 JSON 对象,如果没有 sitemap.json
,则默认为所有页面都允许被索引;sitemap.json
有以下属性:
配置项
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
rules | Object[] | 是 | 索引规则列表 |
完整配置项说明请参考小程序 sitemap 配置
5. 小程序配置文件
⼀个小程序应⽤程序会包括最基本的两种配置⽂件。⼀种是全局的 app.json 和 页面自己的 page.json
注意:配置文件中不能出现注释
5.1. 全局配置 app.json
app.json
是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab
等。普通快速启动项⽬⾥边的 app.json
配置
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle":"black"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
字段的含义
- pages 字段 ⸺⽤于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个⽬录。
- window 字段 ⸺ 定义小程序所有页面的顶部背景颜色,文字颜色定义等。
- 完整的配置信息请参考 app.json
配置项
属性 | 类型 | 必填 | 描述 | 最低版本 |
---|---|---|---|---|
entryPagePath | string | 否 | 小程序默认启动首页 | |
pages | string[] | 是 | 页面路径列表 | |
window | Object | 否 | 全局的默认窗口表现 | |
tabBar | Object | 否 | 底部 tab 栏的表现 | |
networkTimeout | Object | 否 | 网络超时时间 | |
debug | boolean | 否 | 是否开启 debug 模式,默认关闭 | |
functionalPages | boolean | 否 | 是否启用插件功能页,默认关闭 | 2.1.0 |
subpackages | Object[] | 否 | 分包结构配置 | 1.7.3 |
workers | string | 否 | Worker 代码放置的目录 | 1.9.90 |
requiredBackgroundModes | string[] | 否 | 需要在后台使用的能力,如「音乐播放」 | |
plugins | Object | 否 | 使用到的插件 | 1.9.6 |
preloadRule | Object | 否 | 分包预下载规则 | 2.3.0 |
resizable | boolean | 否 | PC 小程序是否支持用户任意改变窗口大小(包括最大化窗口);iPad 小程序是否支持屏幕旋转。默认关闭 | 2.3.0 |
usingComponents | Object | 否 | 全局自定义组件配置 | 开发者工具 1.02.1810190 |
permission | Object | 否 | 小程序接口权限相关设置 | 微信客户端 7.0.0 |
sitemapLocation | string | 是 | 指明 sitemap.json 的位置 | |
style | string | 否 | 指定使用升级后的weui样式 | 2.8.0 |
useExtendedLib | Object | 否 | 指定需要引用的扩展库 | 2.2.1 |
entranceDeclare | Object | 否 | 微信消息用小程序打开 | 微信客户端7.0.9 |
darkmode | boolean | 否 | 小程序支持 DarkMode | 2.11.0 |
themeLocation | string | 否 | 指明 theme.json 的位置,darkmode为true为必填 | 开发者工具 1.03.2004271 |
lazyCodeLoading | string | 否 | 配置自定义组件代码按需注入 | 2.11.1 |
singlePage | Object | 否 | 单页模式相关配置 | 2.12.0 |
5.1.1 pages
用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径(含文件名) 信息。文件名不需要写文件后缀,框架会自动去寻找对应位置的 .json
, .js
, .wxml
, .wxss
四个文件进行处理。
未指定 entryPagePath
时,数组的第一项代表小程序的初始页面(首页)。
小程序中新增/减少页面,都需要对 pages 数组进行修改。
如开发目录为:
├── app.js
├── app.json
├── app.wxss
├── pages
│ │── index
│ │ ├── index.wxml
│ │ ├── index.js
│ │ ├── index.json
│ │ └── index.wxss
│ └── logs
│ ├── logs.wxml
│ └── logs.js
└── utils
则需要在 app.json 中写
{
"pages": ["pages/index/index", "pages/logs/logs"]
}
快速创建一个页面文件
我们可以直接在app.json文件中创建,在pages 字段中写入新添加的路径
我们只需要保存一下,他就是自动创建你这个文件和他所需要的配置文件
如果我想文件打开默认展示 demo01的内容,那我们只需要把demo01放在最前面即可
注意:我们只有在微信开发者工具里编辑app.json文件才会自动给你创建页面,在其他程序中则不会发生效果
5.1.2 window
每一个小程序页面也可以使用 .json
文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖 app.json
的 window
中相同的配置项。文件内容为一个 JSON 对象,有以下属性:
配置项
用于设置小程序的状态栏、导航条、标题、窗口背景色。
属性 | 类型 | 默认值 | 描述 | 最低版本 |
---|---|---|---|---|
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色,如 #000000 | |
navigationBarTextStyle | string | white | 导航栏标题颜色,仅支持 black / white | |
navigationBarTitleText | string | 导航栏标题文字内容 | ||
navigationStyle | string | default | 导航栏样式,仅支持以下值: default 默认样式 custom 自定义导航栏,只保留右上角胶囊按钮。参见注 2。 | iOS/Android 微信客户端 6.6.0,Windows 微信客户端不支持 |
backgroundColor | HexColor | #ffffff | 窗口的背景色 | |
backgroundTextStyle | string | dark | 下拉 loading 的样式,仅支持 dark / light | |
backgroundColorTop | string | #ffffff | 顶部窗口的背景色,仅 iOS 支持 | 微信客户端 6.5.16 |
backgroundColorBottom | string | #ffffff | 底部窗口的背景色,仅 iOS 支持 | 微信客户端 6.5.16 |
enablePullDownRefresh | boolean | false | 是否开启全局的下拉刷新。 详见 Page.onPullDownRefresh | |
onReachBottomDistance | number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为 px。 详见 Page.onReachBottom | |
pageOrientation | string | portrait | 屏幕旋转设置,支持 auto / portrait / landscape 详见 响应显示区域变化 | 2.4.0 (auto) / 2.5.0 (landscape) |
-
注 1:HexColor(十六进制颜色值),如"#ff00ff"
-
注 2:关于
navigationStyle
- iOS/Android 客户端 7.0.0 以下版本,
navigationStyle
只在app.json
中生效。 - iOS/Android 客户端 6.7.2 版本开始,
navigationStyle: custom
对 web-view 组件无效 - 开启 custom 后,低版本客户端需要做好兼容。开发者工具基础库版本切到 1.7.0(不代表最低版本,只供调试用)可方便切到旧视觉
- Windows 客户端 3.0 及以上版本,为了给用户提供更符合桌面软件的使用体验,统一了小程序窗口的导航栏,
navigationStyle: custom
不再生效
- iOS/Android 客户端 7.0.0 以下版本,
-
注 3:
navigationBarTextStyle
只能是黑色或白色 -
-
注4:刷新页面的操作
- 注意backgroundColor指的是下拉刷新页面那一部分的背景颜色,页面的背景颜色在 以
.wxss
结尾的文件中设置
- 注意backgroundColor指的是下拉刷新页面那一部分的背景颜色,页面的背景颜色在 以
5.1.3 tabBar
如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。
配置项
属性 | 类型 | 必填 | 默认值 | 描述 | 最低版本 |
---|---|---|---|---|---|
color | HexColor | 是 | tab 上的文字默认颜色,仅支持十六进制颜色 | ||
selectedColor | HexColor | 是 | tab 上的文字选中时的颜色,仅支持十六进制颜色 | ||
backgroundColor | HexColor | 是 | tab 的背景色,仅支持十六进制颜色 | ||
borderStyle | string | 否 | black | tabbar 上边框的颜色, 仅支持 black / white | |
list | Array | 是 | tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab | ||
position | string | 否 | bottom | tabBar 的位置,仅支持 bottom / top | |
custom | boolean | 否 | false | 自定义 tabBar,见详情 | 2.5.0 |
其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每个项都是一个对象,其属性值如下:
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
pagePath | string | 是 | 页面路径,必须在 pages 中先定义 |
text | string | 是 | tab 上按钮文字 |
iconPath | string | 否 | 图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。 当 position 为 top 时,不显示 icon。 |
selectedIconPath | string | 否 | 选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。 当 position 为 top 时,不显示 icon。 |
创建一个tabBar
设置样式
注意:当我们设置 position
的值为 top
时,我们的底部当行则会跑到上面
5.2 页面配置
这里的 page.json 其实⽤来表示页面目录下的 page.json 这类和小程序页面相关的配置。
开发者可以独立定义每个页面的一些属性,如顶部颜色、是否允许下拉刷新等等。
页面的配置只能设置 app.json 中部分 window 配置项的内容,⻚⾯中配置项会覆盖 app.json 的 window 中相同的配置项。
自定义页面
我们可以自定义一个页面的背景颜色,文字
例如我们给 demo01设置自己专属的顶部样式
记住一定要在 app.json 文件中修改它的展示顺序
6. 模板语法
WXML(WeiXin Markup Language)是框架设计的⼀套标签语⾔,结合基础组件、事件系统,可以构建出页面的结构。
为了方便操作我们根据以前的方式创建一个 demo03文件夹
我们在demo03的demo03.wxml文件中编写页面
在此我们介绍两个标签
1. text 相当于以前web中的 span标签 行内元素 不会换行
2. view 相当于以前web中的 div标签 块级元素 会换行
我们举个例子
<text>1</text>
<text>2</text>
<view>3</view>
<view>4</view>
6.1. 数据绑定
我们的数据都是定义在js文件中
但是我们会发现这里面原先是由数据的,当我们把里面的数据给清空时,我们会发现它会给我们报一个错误和两个警告
第一个警告不用管,是api升级的
其他两个 :
因为我们的js文件中有很多方法
我们可以使用 vscode 进行编译
在 vscode 里面下载一个小程序开发助手的插件,来协助我们开发
他会出现微信小程序的代码提示
由于我们只需要对数据进行绑定,所以那些生命周期函数可以删掉,只留下一个data用来编写数据绑定
//Page Object
Page({
data: {
},
});
6.1.1. 字符串
<!-- 字符串 -->
<view> {{ msg }} </view>
Page({
data: {
msg: 'Hello MINA!'
}
})
6.1.2. 组件属性
<view id="item-{{id}}"> </view>
age({
data: {
id: 0
}
})
6.1.2.1 在标签的属性中使用
<view data-num="{{num}}"> 自定义属性 </view>
Page({
data: {
num: 100000
},
});
6.1.3. bool类型
<view>是否是伪娘:{{isGirl}}</view>
Page({
data: {
isGirl:false,
},
});
6.1.3.1 使用bool类型充当属性
checked属性让复选框被选中
<!-- checkbox 就是以前的复选框
使用bool类型充当属性 checked属性让复选框被选中
-->
<view>
<checkbox checked="{{isChecked}}"></checkbox>
</view>
Page({
data: {
isChecked:false
},
});
在此注意:
-
字符串和花括号之间一定不要存在空格 否则会导致识别失败
以下的写法就是错误的示范:
<checkbox checked=" {{isChecked}}"></checkbox>
- 特别注意:不要直接写
checked="false"
,其计算结果是一个字符串,转成 boolean 类型后代表真值。
6.1.4 object 类型
<!-- object 类型 -->
<view>{{person.age}}</view>
<view>{{person.height}}</view>
<view>{{person.weight}}</view>
<view>{{person.name}}</view>
Page({
data: {
person:{
age:74,
height:147,
weight:200,
name:"富婆"
}
},
});
也可以用扩展运算符 ...
来将一个对象展开
<template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}"></template>
Page({
data: {
obj1: {
a: 1,
b: 2
},
obj2: {
c: 3,
d: 4
}
}
})
最终组合成的对象是 {a: 1, b: 2, c: 3, d: 4, e: 5}
。
如果对象的 key 和 value 相同,也可以间接地表达。
<template is="objectCombine" data="{{foo, bar}}"></template>
Page({
data: {
foo: 'my-foo',
bar: 'my-bar'
}
})
最终组合成的对象是 {foo: 'my-foo', bar:'my-bar'}
。
注意:上述方式可以随意组合,但是如有存在变量名相同的情况,后边的会覆盖前面,如:
<template is="objectCombine" data="{{...obj1, ...obj2, a, c: 6}}"></template>
Page({
data: {
obj1: {
a: 1,
b: 2
},
obj2: {
b: 3,
c: 4
},
a: 5
}
})
最终组合成的对象是 {a: 5, b: 3, c: 6}
。
6.2 运算
运算相当于表达式 (运算 => 表达式)
-
可以在花括号中 加入表达式 – “语句”
-
表达式:指的是一些简单运算 数字运算 字符串拼接 逻辑运算。。。
-
数字的加减乘除
<view>{{1+1}}</view> <view>{{1-1}}</view> <view>{{1*1}}</view> <view>{{1/1}}</view>
-
字符串拼接
<view>{{'1'+'1'}}</view>
-
三元表达式
<view>{{ 10%2===0?'偶数':'奇数' }}</view>
-
-
语句 (但是我们并不能直接加入语句,直接加的话会报错)
- 复杂的代码段
- if else
- switch
- do while。。。
- for
- 复杂的代码段
6.2.1. 三元运算
<view>{{ 10%2===0?'偶数':'奇数' }}</view>
6.2.2 算数运算
<view> {{a + b}} + {{c}} + d </view> <!-- 3 + 3 + d -->
Page({
data: {
a: 1,
b: 2,
c: 3
}
})
6.2.3 逻辑判断
<!-- 首先这个if语句是写在wxml里面的,根据条件来判断来渲染
如果length大于5就显示1,小于则不显示
-->
<view wx:if="{{length > 5}}"> 1 </view>
<!-- 如果一个if满足不了我们的要求,我们再来第二个 -->
<view wx:elif="{{length > 2}}"> 2 </view>
<!-- 如果以上条件都有不符合,那我后面加一个<view wx:else> 3 </view>语句,意思是 如果length没有大于2的,也没有大于5的,那么就实现这个<view> -->
<view wx:else> 3 </view>
Page({
data: {
length: 0
},
});
6.2.4 字符串运算
<view>{{'hello' + name}}</view> <!-- helloundefined -->
如果 name是字符串,并且不是调用过来的变量,而且还没加引号,它会返回一个 undefined
<view>{{'hello' + name}}</view> <!-- helloMINA -->
Page({
data: {
name: 'MINA'
},
});
6.2.5注意
花括号和引号之间如果有空格,将最终被解析成为字符串
6.3 列表渲染
6.3.1 wx:for
在组件上使用 wx:for
控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的:
- 当前项的下标变量名默认为
index
,wx:for-index
可以指定数组当前下标的变量名 - 数组当前项的变量名默认为
item
,wx:for--item
可以指定数组当前元素的变量名
6.3.2 wx:key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用 wx:key
来指定列表中项目的唯一的标识符。
总的来说 : wx:key
⽤来提高数组渲染的性能
wx:key
绑定的值 有如下选择
-
字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中 唯一 的字符串或数字,且 不能动态改变 。
list:[{id:0,name:"炒饭"},{id:1,name:"炒面"}] wx:key="id"
-
保留关键字
*this
代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。list:[1,2,3,4,5] wx:key="*this"
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
如不提供 wx:key
,会报一个 warning
, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
6.3.3 block wx:for
渲染⼀个包含多节点的结构块 block 最终不会变成真正的dom元素
类似 block wx:if
,也可以将 wx:for
用在<block/>
标签上,以渲染一个包含多节点的结构块。例如:
<block wx:for="{{[1, 2, 3]}}">
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
6.3.4 两个注意点:
注意:
当 wx:for
的值为字符串时,会将字符串解析成字符串数组
<view wx:for="array">
{{item}}
</view>
等同于
<view wx:for="{{['a','r','r','a','y']}}">
{{item}}
</view>
注意: 花括号和引号之间如果有空格,将最终被解析成为字符串
<view wx:for="{{[1,2,3]}} ">
{{item}}
</view>
等同于
<view wx:for="{{[1,2,3] + ' '}}" >
{{item}}
</view>
6.4 条件渲染
6.4.1 wx:if
在框架中,使用 wx:if=""
来判断是否需要渲染该代码块:
<view wx:if="{{condition}}"> True </view>
也可以用 wx:elif
和 wx:else
来添加一个 else 块:
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
6.4.2 block wx:if
因为 wx:if
是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/>
标签将多个组件包装起来,并在上边使用 wx:if
控制属性。
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
注意: <block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
6.4.3 hidden
<view hidden="{{condition}}"> True </view
类似 wx:if
wx:if
vs hidden
6.4.4 因为 wx:if
之中的模板也可能包含数据绑定,所以当 wx:if
的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if
也是惰性的,如果在初始渲染条件为 false
,框架什么也不做,在条件第一次变成真的时候才开始局部渲染 。
相比之下,hidden
就简单的多,组件始终会被渲染,只是简单的控制 显示与隐藏 。
一般来说,wx:if
有 更高的切换消耗 而 hidden
有 更高的初始渲染消耗 。因此,如果需要频繁切换的情景下,用 hidden
更好,如果在运行时条件不大可能改变则 wx:if
较好。
总结:
频繁切换 用 hidden
不常使用 ⽤ wx:if
6.5 模板
WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
6.5.1 定义模板
使用 name 属性,作为模板的名字。然后在<template/>
内定义代码片段,如:
<!--
index: int
msg: string
time: string
-->
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
6.5.2 使用模板
使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入,如:
<template is="msgItem" data="{{...item}}"/>
Page({
data: {
item: {
index: 0,
msg: 'this is a template',
time: '2016-09-15'
}
}
})
is 属性可以使用 Mustache 语法,来动态决定具体需要渲染哪个模板:
<template name="odd">
<view> odd </view>
</template>
<template name="even">
<view> even </view>
</template>
<block wx:for="{{[1, 2, 3, 4, 5]}}">
<template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/>
</block>
6.5.3 模板的作用域
模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的 <wxs />
模块。
6.6 引用
WXML 提供两种文件引用方式import
和include
。
6.6.1 import
import
可以在该文件中使用目标文件定义的template
,如:
在 item.wxml 中定义了一个叫item
的template
:
<!-- item.wxml -->
<template name="item">
<text>{{text}}</text>
</template>
在 index.wxml 中引用了 item.wxml,就可以使用item
模板:
<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
6.6.2 import 的作用域
import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。
如:C import B,B import A,在C中可以使用B定义的template
,在B中可以使用A定义的template
,但是C不能使用A定义的template
。
<!-- A.wxml -->
<template name="A">
<text> A template </text>
</template>
<!-- B.wxml -->
<import src="a.wxml"/>
<template name="B">
<text> B template </text>
</template>
<!-- C.wxml -->
<import src="b.wxml"/>
<template is="A"/> <!-- Error! Can not use tempalte when not import A. -->
<template is="B"/>
6.6.3 include
include
可以将目标文件除了 <template/>
<wxs/>
外的整个代码引入,相当于是拷贝到 include
位置,如:
<!-- index.wxml -->
<include src="header.wxml"/>
<view> body </view>
<include src="footer.wxml"/>
<!-- header.wxml -->
<view> header </view>
<!-- footer.wxml -->
<view> footer </view>
7. 案例展示
7.1 创建页面
为了节省时间,我们使用上面所说的简单方式进行编写
在全局配置文件 app.json 中的 pages 属性中,直接编写页面名称,然后保存,工具会自动在 pages 目录下创建对应 的页面
"pages":[
"pages/welcom/welcom",
"pages/posts/posts",
"pages/index/index",
"pages/logs/logs"
],
7.2 初始化项目
7.2.1基本配置
7.2.1.1 配置原因
- 增强编译:让我们可以尽情使用ES的新语法
- 不校验合法域名。。。。:微信小程序要求请求的后台 API 必须是 https 的,我们在本地开发中不 可能安装证书,勾选此项后,本地开发时,微信小程序就可以先忽略这个问题。但小程序上线时, 后台接口必须时 https 协议,且必须配置到域名列表中
7.2.1.2 全局配置文件
在此注意:
-
每次删除目录或文件,小程序都会重新编译,所以当上面列出的目录和文件都删除完成后,控制台有如 下错误 (所以小程序与 vue 一样,都需要一个入口文件,那就是 app.json)
-
app.json 文件不能为空,否则会报如下错误
-
在app.json中只写入 一个
{}
也会报错:
意思是这个文件需要一个 pages 字段
-
当我们写入 pages 字段,不书写内容时,
{ "pages":[] }
这是一个小细节: pages字段中不能为空,至少需要存在一项
-
当我们写入一项,则不会再报错了
{ "pages":[ "pages/welcome/welcome" ] }
附:说一下微信开发者工具创建页面的方式以及 pages/welcome/welcome 各个路径的意义
到现在为止,我们发现程序没有任何错误,那么是不是意味着,程序不需要 app.js 文件呢? 不是的,因为在预览时,就强制要求必须有 app.js 文件
7.2.2 样式单位
使用我们微信小程序的单位rpx进行编写(上面有讲到)
7.3 欢迎页
wxml
<view class="container">
<view class="avatar-container">
<open-data class="avatar" type="userAvatarUrl"></open-data>
</view>
<view class="usernick"><text class="motto">你好,</text>
<open-data type="userNickName" lang="zh_CN"></open-data>
</view>
<view class="button-container">
<navigator url="/pages/posts/posts" class="self-button">进入小程序</navigator>
</view>
</view>
wxss
/* pages/welcom/welcom.wxss */
.container{
display: flex;
flex-direction: column;
align-self: center;
background-color: #b3d4db;
}
.avatar-container{
width: 200rpx;
height: 200rpx;
margin-top: 160rpx;
border-radius: 50%;
/* border: 1px solid black; */
overflow: hidden;
}
.avatar{
width: 200rpx;
height: 200rpx;
}
.usernick{
display: flex;
flex-direction: row;
margin-top: 100rpx;
color: #666;
}
.motto{
font-size: 32rpx;
font-weight: bold;
}
.button-container{
border: 1px solid #405f89;
width: 200rpx;
height: 80rpx;
border-radius: 5px;
text-align: center;
margin-top: 200rpx;
}
.self-button{
font-size: 22rpx;
color: #405f89;
line-height: 88rpx;
font-weight: bold;
}
page{
background-color: #b3d4db;
}
说明
- 微信小程序推荐使用 felx 布局
- .button-containe 是我们定义的一个类似按钮的结构,因为要将小程序的 button 组件改造成这个 样式还是很难的,而且完全没有必要。另外,后面我们将 button-containe 封装成一个组件,所以 页面都可以调用
- navigator 页面跳转组件
- 根目录下新建 images 目录
7.3.1 展示用户信息
上面展示的用户头像和名称都是假数据
可以使用 **open-data**开放能力获取用户实际信息
<!-- <image class="avatar" src="/images/avatar/1.jpg"></image> -->
<!-- 使用 open-data 替换上面的 image -->
<open-data class="avatar" type="userAvatarUrl"></open-data>
虽然可以展示头像,但不是原型的,
.avatar 中设置的属性没有生效 如何解决 外面包裹一层view,设置 view 圆角,并隐藏溢出
<view class="avatar-container">
<open-data class="avatar" type="userAvatarUrl"></open-data>
</view>
7.3.1.1 展示用户昵称
<text class="motto">你好,</text>
<open-data class="motto" type="userNickName"></open-data>
在此注意,我们不能把 不能将 open-data 嵌入到 text 组件中
哪如何放到一行呢?
使用容器包裹起来,并将 motto 样式应用到容器上
<view class="user-nick motto">
<text>你好,</text>
<open-data type="userNickName"></open-data>
</view>
.user-nick{
display: flex;
}
.motto{
margin-top: 100rpx;
color:#666;
font-size: 32rpx;
font-weight: bold;
}
7.4 设置全局导航栏
在 app.json 中,加入如下配置,所有页面生效
"window":{
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "爱读诗",
"navigationBarTextStyle":"black"
},
参见 window 配置
注意:
-
我们可以在文件自己内部的json文件中配置他的局部头部样式,而局部会覆盖全局
-
页面级 json 文件中,不用写到 window 中,因为这里只能配置 window 信息,不能配置其他, 如 pages 等信息
7.5 阅读页面
7.5.1 轮播图
我们可以使用 swiper组件 来编写轮播图,下面是他的属性及作用
滑块视图容器。其中只可放置swiper-item组件,否则会导致未定义的行为。
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
indicator-dots | boolean | false | 否 | 是否显示面板指示点 | 1.0.0 |
indicator-color | color | rgba(0, 0, 0, .3) | 否 | 指示点颜色 | 1.1.0 |
indicator-active-color | color | #000000 | 否 | 当前选中的指示点颜色 | 1.1.0 |
autoplay | boolean | false | 否 | 是否自动切换 | 1.0.0 |
current | number | 0 | 否 | 当前所在滑块的 index | 1.0.0 |
interval | number | 5000 | 否 | 自动切换时间间隔 | 1.0.0 |
duration | number | 500 | 否 | 滑动动画时长 | 1.0.0 |
circular | boolean | false | 否 | 是否采用衔接滑动 | 1.0.0 |
vertical | boolean | false | 否 | 滑动方向是否为纵向 | 1.0.0 |
previous-margin | string | “0px” | 否 | 前边距,可用于露出前一项的一小部分,接受 px 和 rpx 值 | 1.9.0 |
next-margin | string | “0px” | 否 | 后边距,可用于露出后一项的一小部分,接受 px 和 rpx 值 | 1.9.0 |
snap-to-edge | boolean | “false” | 否 | 当 swiper-item 的个数大于等于 2,关闭 circular 并且开启 previous-margin 或 next-margin 的时候,可以指定这个边距是否应用到第一个、最后一个元素 | 2.12.1 |
display-multiple-items | number | 1 | 否 | 同时显示的滑块数量 | 1.9.0 |
easing-function | string | “default” | 否 | 指定 swiper 切换缓动动画类型 | 2.6.5 |
bindchange | eventhandle | 否 | current 改变时会触发 change 事件,event.detail = {current, source} | 1.0.0 | |
bindtransition | eventhandle | 否 | swiper-item 的位置发生改变时会触发 transition 事件,event.detail = {dx: dx, dy: dy} | 2.4.3 | |
bindanimationfinish | eventhandle | 否 | 动画结束时会触发 animationfinish 事件,event.detail 同上 | 1.9.0 |
WXML
<!-- 轮播图 -->
<swiper indicator-dots="{{true}}" indicator-color="orange" indicator-active-color="#fff" autoplay="{{true}}"
vertical="{{false}}">
<swiper-item>
<image src="/image/1.png"></image>
</swiper-item>
<swiper-item>
<image src="/image/2.png"></image>
</swiper-item>
<swiper-item>
<image src="/image/3.png"></image>
</swiper-item>
</swiper>
swiper{
width:100%;
height:460rpx
}
swiper image{
width:100%;
height:460rpx
}
总结:
- swiper 是滑块视图容器,并不是只能作为图片的轮播图
- swiper 中只可放置swiper-item组件,否则会导致未定义的行为,好比 ul 中只能放置 li 标签一样
- swiper-item 仅可放置在swiper组件中,宽高自动设置为100%。
- t通过插槽的方式向 swiper-item 组件中放置元素,swiper-item 实现并不知道,所以如上面案例, swiper-item 中放置的图片的尺寸,需要我们自己定义
- 定义尺寸时,需要设置 image 与 swiper 的宽高一致即可,swiper 不用单独设置,因为其默认宽 高自动设置为swiper的100%
- 关于属性设置:swiper 组件上有几个属性,如果属性值要求为布尔值,需要使用{{}} 将 true 或者 false 包含起来,否则会将值是做字符串,所以,“true” 和 “false” 的布尔值都是“真”,导致无法达 到我们期望的效果
- 当前图片路径来自本地,实际开发中应该来自后台接口响应的数据
7.5.2 阅读列表
在 swiper 下加入如下代码
<!-- 诗词阅读列表 -->
<view class="post-container">
<!-- 头像和发表日期 -->
<view class="post-author-date">
<image class="post-author" src="/images/avatar/2.jpg"></image>
<text class="post-date">2020-04-06</text>
</view>
<!-- 标题 -->
<text class="post-title">碧玉妆成一树高,万条垂下绿丝绦</text>
<image class="post-image" src="/images/posts/biyu.webp"></image>
<text class="post-content">
杨柳的形象美是在于那曼长披拂的枝条。一年一度,它长出了嫩绿的新叶,丝丝下垂,在春风吹拂中,有着一种迷人的意态。这是谁都能欣赏的。古典诗词中,借用这种形象美来形容、比拟美人苗条的身段,婀娜的腰身,也是读者所经常看到的。这诗别出新意,翻转过来。“碧玉妆成一树高”,一开始,杨柳就化身为美人而出现:“万条垂下绿丝绦”,这千条万缕的垂丝,也随之而变成了她的裙带....
</text>
<view class="post-like">
<image class="post-like-image" src="/images/icon/collection.png">
</image>
<text class="post-like-font">99</text>
<image class="post-like-image" src="/images/icon/like.png"></image>
<text class="post-like-font">120</text>
</view>
</view>
说明:
- 收藏和喜欢图片采用的是 iconfont 中的字体图标,下载其 png 格式图片
样式
.post-container {
display: flex;
flex-direction: column;
margin-top: 20rpx;
margin-bottom: 40rpx;
background-color: #fff;
border-bottom: 1px solid #ededed;
padding-bottom: 10rpx;
}
.post-author-date {
/* margin-top:10rpx;
margin-bottom: 20rpx;margin-left: 10rpx; */
margin: 10rpx 0 20rpx 10rpx;
display: flex;
flex-direction: row;
align-items: center;
}
.post-author {
width: 60rpx;
height: 60rpx;
/* vertical-align: middle; */
}
.post-date {
margin-left: 20rpx;
font-size: 26rpx;
/* vertical-align: middle; */
}
.post-title {
font-size: 34rpx;
font-weight: 600;
margin-bottom: 20rpx;
margin-left: 20rpx;
color: #333;
}
.post-image {
width: 100%;
height: 340rpx;
margin-bottom: 30rpx;
}
.post-content {
color: #666;
font-size: 28rpx;
margin-bottom: 20rpx;
margin-left: 20rpx;
line-height: 40rpx;
letter-spacing: 2rpx;
}
.post-like {
display: flex;
flex-direction: row;
align-items: center;
margin-left: 20rpx;
}
.post-like-image {
/* height:32rpx;
width:32rpx; */
font-size: 32rpx;
color: red;
margin-right: 16rpx;
}
/* html */
.post-like-font {
margin-right: 40rpx;
font-size: 26rpx;
}
说明
- 整体仍然采用 flex 布局,包括实现文字与图片垂直居中,使用 flex 布局要比使用其他方式更加简 单直观
7.5.2 使用字体图标
由于使用图片会出现很多问题,所以我们讲上面收藏和喜欢使用字体图标来代替图片
7.5.2.1 使用图片会出现的问题:
- 图片尺寸固定,某些尺寸屏幕上可能造成浪费
- 难以修改图片颜色
7.5.2.2 使用图标字体代替图片的步骤:
-
添加字体图标到购物车
-
将其添加至项目
-
在项目中选中 Font class ,然后选择 “查看在线字体”,然后生成在线地址
-
地址栏中访问上面的地址,查看生成的代码,然后右键另存为到项目文件夹中,修改扩展名为 wxss,保存到根目录下
-
在根目录下的 app.wxss 文件中,使用下面代码引入
@import '/iconfont.wxss'
-
最后在页面或组件中直接使用即可
<text class="iconfont icon-Like"></text>
-
所以修改我们posts 页面中的代码
<view class="post-like"> <!-- <image class="post-like-image" src="/images/icon/collection.png"></image> --> <text class="post-like-image iconfont icon-shoucang1"></text> <text class="post-like-font">{{postData.collection}}</text> <!-- <image class="post-like-image" src="/images/icon/like.png"></image> --> <text class="post-like-image iconfont icon-shouchang"></text> <text class="post-like-font">{{postData.reading}}</text> </view>
-
对 post-like-image 样式类也要做适当的修改
.post-like-image { /* height:32rpx; width:32rpx; */ font-size: 32rpx; color: red; margin-right: 16rpx; }
7.5.3 动态数据
实际开发中,数据应该从后台api获取
这是使用基于 mock 技术的 https://www.fastmock.site/ ps:下面有对 mock的讲解
posts.js 代码
data: {
postsList: []
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
const url=`https://www.fastmock.site/mock/feab55dd20334e49edf0d5adb2f79cbe/libaiserver/api/posts`wx.request({
url: url,
success:(res)=> {
this.setData({
postsList: res.data.data
})
}
})
修改 posts.wxml
<block wx:for="{{postsList}}" wx:key="id">
<view class="post-container">
<!-- 头像和发表日期 -->
<view class="post-author-date">
<image class="post-author" src="{{item.avatar}}"></image>
<text class="post-date">{{item.date}}</text>
</view>
<!-- 标题 -->
<text class="post-title">{{item.title}}</text>
<image class="post-image" src="{{item.imgSrc}}"></image>
<text class="post-content">{{item.desc}}</text>
<view class="post-like">
<!-- <image class="post-like-image"src="/images/icon/collection.png"></image> -->
<text class="post-like-image iconfont icon-collection"></text>
<text class="post-like-font">{{item.collection}}</text>
<!-- <image class="post-like-image" src="/images/icon/like.png"></image> -->
<text class="post-like-image iconfont icon-Like"></text>
<text class="post-like-font">{{item.reading}}</text>
</view>
</view>
</block>
- 小程序建议,如果便利的模板结构比较复杂,使用 block 进行包裹,并在 block 上进行遍历
7.5.4 页面跳转
点击 welcome 中的 进入小程序,跳转到 posts 页面
参考 路由api
- navigateTo :保留当前页面,跳转到应用内的某个页面,页面左上角会出现返回标志,再返回本页面 onShow 会被触发,离开页面时 onHide 会触发
- redirectTo:关闭当前页面,跳转到应用内的某个页面,页面左上角不会出现返回标志,再返回本页面 onLoad、onShow、onReady 会被触发,相当于页面首次加载,离开页面时 onUnLoad 会触发
- navigateTo 适合于父子关系的页面,redirectTo适合级别相等的页面
直接跳转
welcome.wxml
<view class="button-container">
<navigator url="/pages/posts/posts" class="self-button">进入小程序</navigator>
</view>
点击跳转
welcome.wxml
<view class="button-container" bind:tap="toToPosts">
<text class="self-button">进入小程序</text>
</view>
welcome.js
toToPosts:function(){
wx.redirectTo({
url: '/pages/posts/posts',
})
}
7.5.5 bind:tap 和 catch:tap
bindtap和catchtap都属于点击事件函数,将事件绑定到组件上,点击组件后可以触发函数。
二者的区别在于是否冒泡事件。
bind:tap :冒泡
catch:tap:阻止事件冒泡
冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
7.5.6 点击头像查看大图
利用 图片预览API
posts.js 中的 previeImg 函数代码
// 预览头像
previeImg(event){
let imgArr=[]
this.data.postsList.forEach(item=>{
imgArr.push({url:item.imgSrc})
})
console.log(imgArr)
wx.previewMedia({
sources:imgArr
})
},
未完待续。。。。。。
8. Mock.js
Mock.js 是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试。提供了以下模拟功能:
- 根据数据模板生成模拟数据
- 模拟 Ajax 请求,生成并返回模拟数据
- 基于 HTML 模板生成模拟数据
8.1 在线编辑器
8.2 下载
8.2.1 Node (CommonJS)
// 安装
npm install mockjs
// 使用
var Mock = require('mockjs');
var data = Mock.mock({
'list|1-10': [{
'id|+1': 1
}]
});
console.log(JSON.stringify(data, null, 4))
8.3 语法规范
Mock.js 的语法规范包括两部分:
- 数据模板定义(Data Temaplte Definition,DTD)
- 数据占位符定义(Data Placeholder Definition,DPD)
8.3.1 数据模板定义 DTD
数据模板中的每个属性由 3 部分构成:属性名、生成规则、属性值:
// 属性名 name
// 生成规则 rule
// 属性值 value
'name|rule': value
注意:
- 属性名 和 生成规则 之间用
|
分隔。 - 生成规则 是可选的。
- 生成规则 有 7 种格式:
'name|min-max': value
'name|count': value
'name|min-max.dmin-dmax': value
'name|min-max.dcount': value
'name|count.dmin-dmax': value
'name|count.dcount': value
'name|+step': value
- 生成规则 的 含义 需要依赖 属性值 才能确定。
- 属性值 中可以含有
@占位符
。 - 属性值 还指定了最终值的初始值和类型。
8.3.1.1 生成规则和示例:
1. 属性值是字符串
String
'name|min-max': 'value'
通过重复'value'
生成一个字符串,重复次数大于等于min
,小于等于max
。'name|count': 'value'
通过重复'value'
生成一个字符串,重复次数等于count
。
2. 属性值是数字
Number
-
'name|+1': 100
属性值自动加 1,初始值为 100 -
'name|1-100': 100
生成一个大于等于 1、小于等于 100 的整数,属性值 100 只用来确定类型。 -
'name|1-100.1-10': 100
生成一个浮点数,整数部分大于等于 1、小于等于 100,小数部分保留 1 到 10 位。{ 'number1|1-100.1-10': 1, 'number2|123.1-10': 1, 'number3|123.3': 1, 'number4|123.10': 1.123 } // => { "number1": 12.92, "number2": 123.51, "number3": 123.777, "number4": 123.1231091814 }
3. 属性值是布尔型
Boolean
'name|1': value
随机生成一个布尔值,值为 true 的概率是 1/2,值为 false 的概率是 1/2。'name|min-max': value
随机生成一个布尔值,值为value
的概率是min / (min + max)
,值为!value
的概率是max / (min + max)
。
4. 属性值是对象
Object
'name|min-max': {}
从属性值{}
中随机选取min
到max
个属性。'name|count': {}
从属性值{}
中随机选取count
个属性。
5. 属性值是数组
Array
'name|1': [{}, {} ...]
从属性值[{}, {} ...]
中随机选取 1 个元素,作为最终值。'name|min-max': [{}, {} ...]
通过重复属性值[{}, {} ...]
生成一个新数组,重复次数大于等于min
,小于等于max
。'name|count': [{}, {} ...]
通过重复属性值[{}, {} ...]
生成一个新数组,重复次数为count
。
6.属性值是数组
Function
'name': function(){}
执行函数 function(){}
,取其返回值作为最终的属性值,上下文为 'name'
所在的对象。
8.3.2 数据占位符定义 DPD
占位符 只是在属性值字符串中占个位置,并不出现在最终的属性值中。占位符 的格式为:
@占位符
@占位符(参数 [, 参数])
注意:
-
用
@
来标识其后的字符串是 占位符。 -
占位符 引用的是
Mock.Random
中的方法。 -
通过
Mock.Random.extend()
来扩展自定义占位符。 -
占位符 也可以引用 数据模板 中的属性。
-
占位符 会优先引用 数据模板 中的属性。
{ name: { first: '@FIRST', middle: '@FIRST', last: '@LAST', full: '@first @middle @last' } } // => { "name": { "first": "Charles", "middle": "Brenda", "last": "Lopez", "full": "Charles Brenda Lopez" } }
8.3.3 Mock.Random
Mock.Random 是一个工具类,用于生成各种随机数据。Mock.Random 的方法在数据模板中称为“占位符”,引用格式为 @占位符(参数 [, 参数])
。例如:
var Random = Mock.Random;
Random.email()
// => "n.clark@miller.io"
Mock.mock('@EMAIL')
// => "y.lee@lewis.org"
Mock.mock( { email: '@EMAIL' } )
// => { email: "v.lewis@hall.gov" }
可以在上面的例子中看到,直接调用 ‘Random.email()’ 时方法名 email()
是小写的,而数据模板中的 @EMAIL
却是大写。这并非对数据模板中的占位符做了特殊处理,也非强制的编写方式,事实上在数据模板中使用小写的 @email
也可以达到同样的效果。不过,这是建议的编码风格,以便在阅读时从视觉上提高占位符的识别度,快速识别占位符和普通字符。
在浏览器中,为了减少需要拼写的字符,Mock.js 把 Mock.Random 暴露给了 window 对象,使之成为全局变量,从而可以直接访问 Random。因此上面例子中的 var Random = Mock.Random;
可以省略。在后面的例子中,也将做同样的处理。
在 Node.js 中,仍然需要通过
Mock.Random
访问。
Mock.Random 提供的完整方法(占位符)如下:
Type | Method |
---|---|
Basics | boolean, natural, integer, float, character, string, range, date, time, datetime, now |
Image | image, dataImage |
Color | color |
Text | paragraph, sentence, word, title |
Name | first, last, name |
Web | url, domain, email, ip, tld |
Address | area, region |
Helpers | capitalize, upper, lower, pick, shuffle |
Miscellaneous | guid, id |
Mock.Random 中的方法与数据模板的 @占位符
一一对应,在需要时可以为 Mock.Random 扩展方法,然后在数据模板中通过 @扩展方法
引用。例如:
Random.extend({
constellations: ['白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '摩羯座', '水瓶座', '双鱼座'],
constellation: function(date){
return this.pick(this.constellations)
}
})
Random.constellation()
// => "水瓶座"
Mock.mock('@CONSTELLATION')
// => "天蝎座"
Mock.mock({ constellation: '@CONSTELLATION'})
// => { constellation: "射手座" }
8.3.3.1 Basics
方法 | 意义 | 用法 |
---|---|---|
Random.boolean(min, max, cur) | 返回一个随机的布尔值。 | Random.boolean() Random.boolean(min, max, cur) |
Random.natural(min, max) | 返回一个随机的自然数(大于等于 0 的整数) | Random.natural() Random.natural(min) Random.natural(min, max) |
Random.integer(min, max) | 返回一个随机的整数。 | Random.integer() Random.integer(min) Random.integer(min, max) |
Random.float(min, max, dmin, dmax) | 返回一个随机的浮点数。 | Random.float() Random.float(min) Random.float(min, max) Random.float(min, max, dmin) Random.float(min, max, dmin, dmax) |
Random.character(pool) | 返回一个随机字符。 | Random.character() Random.character(‘lower/upper/number/symbol’) Random.character(pool) |
Random.string(pool, min, max) | 返回一个随机字符串。 | Random.string() Random.string( length ) Random.string( pool, length ) Random.string( min, max ) Random.string( pool, min, max ) |
Random.range(start, stop, step) | 返回一个整型数组。 | Random.range(stop) Random.range(start, stop) Random.range(start, stop, step) |
Random.date(format) | 返回一个随机的日期字符串。 | Random.date() Random.date(format) |
Random.time(format) | 返回一个随机的时间字符串 | Random.time() Random.time(format) |
Random.datetime(format) | 返回一个随机的日期和时间字符串。 | Random.datetime() Random.datetime(format) |
Random.now(unit, format) | 返回当前的日期和时间字符串。 | Ranndom.now(unit, format) Ranndom.now() Ranndom.now(format) Ranndom.now(unit) |
8.3.3.1.1 Random.boolean(min, max, cur)
返回一个随机的布尔值。
参数的含义和默认值如下所示:
- 参数 min:可选。指示参数 cur 出现的概率。概率计算公式为
min / (min + max)
。该参数的默认值为 1,即有 50% 的概率返回参数 cur。 - 参数 max:可选。指示参数 cur 的相反值(!cur)出现的概率。概率计算公式为
max / (min + max)
。该参数的默认值为 1,即有 50% 的概率返回参数 cur。 - 参数 cur:可选。可选值为布尔值 true 或 false。如果未传入任何参数,则返回 true 和 false 的概率各为 50%。该参数没有默认值,在该方法的内部,依据原生方法 Math.random() 返回的(浮点)数来计算和返回布尔值,例如在最简单的情况下,返回值是表达式
Math.random() >= 0.5
的执行结果。
使用示例如下所示:
Random.boolean()
// => true
Random.boolean(1, 9, true)
// => false
Random.bool()
// => false
Random.bool(1, 9, false)
// => true
8.3.3.1.2 Random.natural(min, max)
返回一个随机的自然数(大于等于 0 的整数)。
参数的含义和默认值如下所示:
- 参数 min:可选。指示随机自然数的最小值。默认值为 0。
- 参数 max:可选。指示随机自然数的最小值。默认值为 9007199254740992。
使用示例如下所示:
Random.natural()
// => 1002794054057984
Random.natural(10000)
// => 71529071126209
Random.natural(60, 100)
// => 77
8.3.3.1.3 Random.integer(min, max)
返回一个随机的整数。
参数的含义和默认值如下所示:
- 参数 min:可选。指示随机整数的最小值。默认值为 -9007199254740992。
- 参数 max:可选。指示随机整数的最大值。默认值为 9007199254740992。
使用示例如下所示:
Random.integer()
// => -3815311811805184
Random.integer(10000)
// => 4303764511003750
Random.integer(60,100)
// => 96
8.3.3.1.4 Random.float(min, max, dmin, dmax)
返回一个随机的浮点数。
参数的含义和默认值如下所示:
- 参数 min:可选。整数部分的最小值。默认值为 -9007199254740992。
- 参数 max:可选。整数部分的最大值。默认值为 9007199254740992。
- 参数 dmin:可选。小数部分位数的最小值。默认值为 0。
- 参数 dmin:可选。小数部分位数的最大值。默认值为 17。
使用示例如下所示:
Random.float()
// => -1766114241544192.8
Random.float(0)
// => 556530504040448.25
Random.float(60, 100)
// => 82.56779679549358
Random.float(60, 100, 3)
// => 61.718533677927894
Random.float(60, 100, 3, 5)
// => 70.6849
8.3.3.1.5 Random.character(pool)
返回一个随机字符。
参数的含义和默认值如下所示:
-
参数 pool:可选。字符串。表示字符池,将从中选择一个字符返回。
-
如果传入
'lower'
或'upper'
、'number'
、'symbol'
,表示从内置的字符池从选取:{ lower: "abcdefghijklmnopqrstuvwxyz", upper: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", number: "0123456789", symbol: "!@#$%^&*()[]" }
-
如果未传入该参数,则从
'lower' + 'upper' + 'number' + 'symbol'
中随机选取一个字符返回。
-
使用示例如下所示:
Random.character()
// => "P"
Random.character('lower')
// => "y"
Random.character('upper')
// => "X"
Random.character('number')
// => "1"
Random.character('symbol')
// => "&"
Random.character('aeiou')
// => "u"
8.3.3.1.6 Random.string(pool, min, max)
返回一个随机字符串。
参数的含义和默认值如下所示:
-
参数 pool:可选。字符串。表示字符池,将从中选择一个字符返回。
-
如果传入
'lower'
或'upper'
、'number'
、'symbol'
,表示从内置的字符池从选取:{ lower: "abcdefghijklmnopqrstuvwxyz", upper: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", number: "0123456789", symbol: "!@#$%^&*()[]" }
-
如果未传入该参数,则从
'lower' + 'upper' + 'number' + 'symbol'
中随机选取一个字符返回。
-
-
参数 min:可选。随机字符串的最小长度。默认值为 3。
-
参数 max:可选。随机字符串的最大长度。默认值为 7。
使用示例如下所示:
Random.string()
// => "pJjDUe"
Random.string( 5 )
// => "GaadY"
Random.string( 'lower', 5 )
// => "jseqj"
Random.string( 7, 10 )
// => "UuGQgSYk"
Random.string( 'aeiou', 1, 3 )
// => "ea"
8.3.3.1.7 Random.range(start, stop, step)
返回一个整型数组。
参数的含义和默认值如下所示:
- 参数 start:必选。数组中整数的起始值。
- 参数 stop:可选。数组中整数的结束值(不包含在返回值中)。
- 参数 step:可选。数组中整数之间的步长。默认值为 1。
使用示例如下所示:
Random.range(10)
// => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Random.range(3, 7)
// => [3, 4, 5, 6]
Random.range(1, 10, 2)
// => [1, 3, 5, 7, 9]
Random.range(1, 10, 3)
// => [1, 4, 7]
8.3.3.1.8 Random.date(format)
- Random.date()
- Random.date(format)
返回一个随机的日期字符串。
参数的含义和默认值如下所示:
- 参数 format:可选。指示生成的日期字符串的格式。默认值为
yyyy-MM-dd
。可选的占位符参考自 Ext.Date,如下所示:
Format | Description | Example |
---|---|---|
yyyy | A full numeric representation of a year, 4 digits | 1999 or 2003 |
yy | A two digit representation of a year | 99 or 03 |
y | A two digit representation of a year | 99 or 03 |
MM | Numeric representation of a month, with leading zeros | 01 to 12 |
M | Numeric representation of a month, without leading zeros | 1 to 12 |
dd | Day of the month, 2 digits with leading zeros | 01 to 31 |
d | Day of the month without leading zeros | 1 to 31 |
HH | 24-hour format of an hour with leading zeros | 00 to 23 |
H | 24-hour format of an hour without leading zeros | 0 to 23 |
hh | 12-hour format of an hour without leading zeros | 1 to 12 |
h | 12-hour format of an hour with leading zeros | 01 to 12 |
mm | Minutes, with leading zeros | 00 to 59 |
m | Minutes, without leading zeros | 0 to 59 |
ss | Seconds, with leading zeros | 00 to 59 |
s | Seconds, without leading zeros | 0 to 59 |
SS | Milliseconds, with leading zeros | 000 to 999 |
S | Milliseconds, without leading zeros | 0 to 999 |
A | Uppercase Ante meridiem and Post meridiem | AM or PM |
a | Lowercase Ante meridiem and Post meridiem | am or pm |
T | Milliseconds, since 1970-1-1 00:00:00 UTC | 759883437303 |
使用示例如下所示:
Random.date()
// => "2002-10-23"
Random.date('yyyy-MM-dd')
// => "1983-01-29"
Random.date('yy-MM-dd')
// => "79-02-14"
Random.date('y-MM-dd')
// => "81-05-17"
Random.date('y-M-d')
// => "84-6-5"
8.3.3.1.9 Random.time(format)
返回一个随机的时间字符串。
参数的含义和默认值如下所示:
- 参数 format:可选。指示生成的时间字符串的格式。默认值为
HH:mm:ss
。可选的占位符参考自 Ext.Date,请参见 Random.date(format)。
使用示例如下所示:
Random.time()
// => "00:14:47"
Random.time('A HH:mm:ss')
// => "PM 20:47:37"
Random.time('a HH:mm:ss')
// => "pm 17:40:00"
Random.time('HH:mm:ss')
// => "03:57:53"
Random.time('H:m:s')
// => "3:5:13"
8.3.3.1.10 Random.datetime(format)
返回一个随机的日期和时间字符串。
参数的含义和默认值如下所示:
- 参数 format:可选。指示生成的日期和时间字符串的格式。默认值为
yyyy-MM-dd HH:mm:ss
。可选的占位符参考自 Ext.Date,请参见 Random.date(format)。
使用示例如下所示:
Random.datetime()
// => "1977-11-17 03:50:15"
Random.datetime('yyyy-MM-dd A HH:mm:ss')
// => "1976-04-24 AM 03:48:25"
Random.datetime('yy-MM-dd a HH:mm:ss')
// => "73-01-18 pm 22:12:32"
Random.datetime('y-MM-dd HH:mm:ss')
// => "79-06-24 04:45:16"
Random.datetime('y-M-d H:m:s')
// => "02-4-23 2:49:40"
8.3.3.1.11 Random.now(unit, format)
返回当前的日期和时间字符串。
参数的含义和默认值如下所示:
- 参数 unit:可选。表示时间单元,用于对当前日期和时间进行格式化。可选值有:
year
、month
、week
、day
、hour
、minute
、second
、week
,默认不会格式化。 - 参数 format:可选。指示生成的日期和时间字符串的格式。默认值为
yyyy-MM-dd HH:mm:ss
。可选的占位符参考自 Ext.Date,请参见 Random.date(format)。
Random.now() 的实现参考了 (Moment.js)[http://momentjs.cn/docs/#/manipulating/start-of/]。
使用示例如下所示:
Random.now()
// => "2014-04-29 20:08:38 "
Random.now('day', 'yyyy-MM-dd HH:mm:ss SS')
// => "2014-04-29 00:00:00 000"
Random.now('day')
// => "2014-04-29 00:00:00 "
Random.now('yyyy-MM-dd HH:mm:ss SS')
// => "2014-04-29 20:08:38 157"
Random.now('year')
// => "2014-01-01 00:00:00"
Random.now('month')
// => "2014-04-01 00:00:00"
Random.now('week')
// => "2014-04-27 00:00:00"
Random.now('day')
// => "2014-04-29 00:00:00"
Random.now('hour')
// => "2014-04-29 20:00:00"
Random.now('minute')
// => "2014-04-29 20:08:00"
Random.now('second')
// => "2014-04-29 20:08:38"
8.3.3.4 Image
方法 | 意义 | 用法 |
---|---|---|
Random.image(size, background, foreground, format, text) | 生成一个随机的图片地址。 | Random.image() Random.image(size) Random.image(size, background) Random.image(size, background, text) Random.image(size, background, foreground, text) Random.image(size, background, foreground, format, text) |
Random.dataImage(size, text) | 生成一段随机的 Base64 图片编码。 | Random.dataImage() Random.dataImage(size) Random.dataImage(size, text) |
8.3.3.4.1 Random.image(size, background, foreground, format, text)
生成一个随机的图片地址。
Random.image() 用于生成高度自定义的图片地址,一般情况下,应该使用更简单的 Random.dataImage()。
参数的含义和默认值如下所示:
-
参数 size:可选。指示图片的宽高,格式为
'宽x高'
。默认从下面的数组中随机读取一个:[ '300x250', '250x250', '240x400', '336x280', '180x150', '720x300', '468x60', '234x60', '88x31', '120x90', '120x60', '120x240', '125x125', '728x90', '160x600', '120x600', '300x600' ]
-
参数 background:可选。指示图片的背景色。默认值为 ‘#000000’。
-
参数 foreground:可选。指示图片的前景色(文件)。默认值为 ‘#FFFFFF’。
-
参数 format:可选。指示图片的格式。默认值为 ‘png’,可选值包括:‘png’、‘gif’、‘jpg’。
-
参数 text:可选。指示图片上的文字。默认为参数 size。
使用示例如下所示:
Random.image()
// => "http://dummyimage.com/125x125"
Random.image('200x100')
// => "http://dummyimage.com/200x100"
Random.image('200x100', '#fb0a2a')
// => "http://dummyimage.com/200x100/fb0a2a"
Random.image('200x100', '#02adea', 'Hello')
// => "http://dummyimage.com/200x100/02adea&text=Hello"
Random.image('200x100', '#00405d', '#FFF', 'Mock.js')
// => "http://dummyimage.com/200x100/00405d/FFF&text=Mock.js"
Random.image('200x100', '#ffcc33', '#FFF', 'png', '!')
// => "http://dummyimage.com/200x100/ffcc33/FFF.png&text=!"
生成的路径所对应的图片如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4iuzNKwT-1618575939603)(http://dummyimage.com/200x100/fb0a2a)]
8.3.3.4.2 Random.dataImage(size, text)
生成一段随机的 Base64 图片编码。
如果需要生成高度自定义的图片,请使用 Random.image()。
参数的含义和默认值如下所示:
-
参数 size:可选。指示图片的宽高,格式为
'宽x高'
。默认从下面的数组中随机读取一个:[ '300x250', '250x250', '240x400', '336x280', '180x150', '720x300', '468x60', '234x60', '88x31', '120x90', '120x60', '120x240', '125x125', '728x90', '160x600', '120x600', '300x600' ]
-
参数 text:可选。指示图片上的文字。默认为参数 size。
图片的背景色是随机的,取值范围参考自 http://brandcolors.net/。
使用示例如下所示:
Random.dataImage()
// => "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAYAAACPgGwlAAAFJElEQVR4Xu2dS0hUURzG/1Yqlj2otJe10AqCoiJaFFTUpgcUhLaKCIogKCEiCl0U1SIIF1EIQlFEtCmkpbWSHlAQYRYUlI9Ie6nYmI9hfIx1LpzL3PGO/aeuM/r/f7PRufe7d873/ea75xw3ZjTumDtMeKlKIAPQVfF2zAK6PuaArpA5oAO6xgQUesacDugKE1BoGU0HdIUJKLSMpgO6wgQUWkbTAV1hAgoto+mArjABhZbRdEBXmIBCy2g6oCtMQKFlNB3QFSag0DKaDugKE1BoGU0HdIUJKLSMpgO6wgQUWkbTAV1hAgoto+mArjABhZbRdEBXmIBCy2g6oCtMQKFlNB3QFSag0DKaDugKE1BoGU0HdIUJKLSMpgO6wgQUWkbTAV1hAgoto+mArjABhZbRdEBXmIBCy2g6oCtMQKFlNB3QFSag0DKaDugKE1BoGU0HdIUJKLQ8bpo+fft+ylxYSJ23LvpisOfNST/N7ENniYa9/0xy4GsTdT+6+09Yx9t4/slEgovSDt2EO3P3YcoqWuUMsWln3oihFlTWUlbhSvf4UKid2iqOUfhVrXussKZ9xHXh10/oW1lxUnmNt/EkNXimOK3QTTtn7Sv1DDUees66rTT/3B0a/NFCvc9raOqf9+YL0PfiIX0/f8ADPdrXTZEPde6xyMd66rx5wXlvnwThN8/cL4ttc7S3i0L3rjqaVI2HyWdMZGmFbhwtvv7cgZm7ZS9NyS/wbboBb1ttwQy2tdLng2s90OOPxSa24FI15azZTAOtDdRyZAOZe84ru0GTps2g0P1r7pcjVeMZE5rMm6Yduh3nktt1CaHHesk/XUW5W4sp8v4lfTm5ywN9eCBCQz/baOBLE0Ua3rgg4z/DPCUmz5xD2SvWU6IpIBXjYTIKXDahoNtHvUmho/KMZ5HmN6f31FZT2+Wjbmix12dkZtNoTwYO9P8dT+A0mTecMNBNwPmnKmnyrDyKhxnv1U4B0d5f9KmkyHPaPinMwfYrJxKu7v8GPajxMDkFKpsQ0JMJ2KZjmm8e9817CjxNt/O4Odjf+JZaj2/zDXQ06EGNJ1CSSdws7dDNAsvsr7OXr3UWVeG6x87wv5WXOD9jAzZbtf7md669nscP3KbOLa2gaE+Xc27axl2UWbB0xLxvFmnmuJnTzU/7e+wuIJXjSYJToNK0Q/ebi41Du3Xz20bZBGJX3fH3Mav0jqpyd9Xvt3o3W0Ezt492H/tZQY8nUIpJ3izt0J39s8/L7q9N03NWb/LVhOuferZyWYuX0WDnD2evHv+XOPs5sdc4+/RFRX+eECFnn25eqRpPkpwClacdeqBucDNWAoDOikmWCNBl8WS5AXRWTLJEgC6LJ8sNoLNikiUCdFk8WW4AnRWTLBGgy+LJcgPorJhkiQBdFk+WG0BnxSRLBOiyeLLcADorJlkiQJfFk+UG0FkxyRIBuiyeLDeAzopJlgjQZfFkuQF0VkyyRIAuiyfLDaCzYpIlAnRZPFluAJ0VkywRoMviyXID6KyYZIkAXRZPlhtAZ8UkSwTosniy3AA6KyZZIkCXxZPlBtBZMckSAbosniw3gM6KSZYI0GXxZLkBdFZMskSALosnyw2gs2KSJQJ0WTxZbgCdFZMsEaDL4slyA+ismGSJAF0WT5YbQGfFJEsE6LJ4stwAOismWSJAl8WT5QbQWTHJEgG6LJ4sN4DOikmWCNBl8WS5AXRWTLJEgC6LJ8sNoLNikiUCdFk8WW4AnRWTLNFvXskYA3TG3JwAAAAASUVORK5CYII="
因为图片的 Base64 编码比较长,下面只显示生成的图片效果。
Random.dataImage('200x100')
Random.dataImage('300x100', 'Hello Mock.js!')
[外链图片转存中…(img-OUxP2BP5-1618576234209)]
8.3.3.5 Color
方法 | 意义 | 用法 | 案例 |
---|---|---|---|
Random.color() | 随机生成一个颜色,格式为 ‘#RRGGBB’。 | Random.color() | Random.color() // => “#3538b2” |
8.3.3.6 Text
方法 | 意义 | 用法 |
---|---|---|
Random.paragraph(len) | 随机生成一段文本。 | Random.paragraph() Random.paragraph(len) Random.paragraph(min, max) |
Random.sentence(len) | 随机生成一个句子,第一个的单词的首字母大写。 | Random.sentence() Random.sentence(len) Random.sentence(min, max) |
Random.word(len) | 随机生成一个单词 | Random.word() Random.word(len) Random.word(min, max) |
Random.title(len) | 随机生成一句标题,其中每个单词的首字母大写。 | Random.title() Random.title(len) Random.title(min, max) |
8.3.3.6.1 Random.paragraph(len)
随机生成一段文本。
参数的含义和默认值如下所示:
- 参数 len:可选。指示文本中句子的个数。默认值为 3 到 7 之间的随机数。
- 参数 min:可选。指示文本中句子的最小个数。默认值为 3。
- 参数 max:可选。指示文本中句子的最大个数。默认值为 7。
使用示例如下所示:
Random.paragraph()
// => "Yohbjjz psxwibxd jijiccj kvemj eidnus disnrst rcconm bcjrof tpzhdo ncxc yjws jnmdmty. Dkmiwza ibudbufrnh ndmcpz tomdyh oqoonsn jhoy rueieihtt vsrjpudcm sotfqsfyv mjeat shnqmslfo oirnzu cru qmpt ggvgxwv jbu kjde. Kzegfq kigj dtzdd ngtytgm comwwoox fgtee ywdrnbam utu nyvlyiv tubouw lezpkmyq fkoa jlygdgf pgv gyerges wbykcxhwe bcpmt beqtkq. Mfxcqyh vhvpovktvl hrmsgfxnt jmnhyndk qohnlmgc sicmlnsq nwku dxtbmwrta omikpmajv qda qrn cwoyfaykxa xqnbv bwbnyov hbrskzt. Pdfqwzpb hypvtknt bovxx noramu xhzam kfb ympmebhqxw gbtaszonqo zmsdgcku mjkjc widrymjzj nytudruhfr uudsitbst cgmwewxpi bye. Eyseox wyef ikdnws weoyof dqecfwokkv svyjdyulk glusauosnu achmrakky kdcfp kujrqcq xojqbxrp mpfv vmw tahxtnw fhe lcitj."
Random.paragraph(2)
// => "Dlpec hnwvovvnq slfehkf zimy qpxqgy vwrbi mok wozddpol umkek nffjcmk gnqhhvm ztqkvjm kvukg dqubvqn xqbmoda. Vdkceijr fhhyemx hgkruvxuvr kuez wmkfv lusfksuj oewvvf cyw tfpo jswpseupm ypybap kwbofwg uuwn rvoxti ydpeeerf."
Random.paragraph(1, 3)
// => "Qdgfqm puhxle twi lbeqjqfi bcxeeecu pqeqr srsx tjlnew oqtqx zhxhkvq pnjns eblxhzzta hifj csvndh ylechtyu."
8.3.3.6.2 Random.sentence(len)
随机生成一个句子,第一个的单词的首字母大写。
参数的含义和默认值如下所示:
- 参数 len:可选。指示句子中单词的个数。默认值为 12 到 18 之间的随机数。
- 参数 min:可选。指示句子中单词的最小个数。默认值为 12。
- 参数 max:可选。指示句子中单词的最大个数。默认值为 18。
使用示例如下所示:
Random.sentence()
// => "Jovasojt qopupwh plciewh dryir zsqsvlkga yeam."
Random.sentence(5)
// => "Fwlymyyw htccsrgdk rgemfpyt cffydvvpc ycgvno."
Random.sentence(3, 5)
// => "Mgl qhrprwkhb etvwfbixm jbqmg."
8.3.3.6.3 Random.word(len)
随机生成一个单词。
参数的含义和默认值如下所示:
- 参数 len:可选。指示单词中字符的个数。默认值为 3 到 10 之间的随机数。
- 参数 min:可选。指示单词中字符的最小个数。默认值为 3。
- 参数 max:可选。指示单词中字符的最大个数。默认值为 10。
使用示例如下所示:
Random.word()
// => "fxpocl"
Random.word(5)
// => "xfqjb"
Random.word(3, 5)
// => "kemh"
目前单词中的字符是随机的小写字母,未来会根据词法生成“可读”的单词。
8.3.3.6.4 Random.title(len)
随机生成一句标题,其中每个单词的首字母大写。
参数的含义和默认值如下所示:
- 参数 len:可选。指示单词中字符的个数。默认值为 3 到 7 之间的随机数。
- 参数 min:可选。指示单词中字符的最小个数。默认值为 3。
- 参数 max:可选。指示单词中字符的最大个数。默认值为 7。
使用示例如下所示:
Random.title()
// => "Rduqzr Muwlmmlg Siekwvo Ktn Nkl Orn"
Random.title(5)
// => "Ahknzf Btpehy Xmpc Gonehbnsm Mecfec"
Random.title(3, 5)
// => "Hvjexiondr Pyickubll Owlorjvzys Xfnfwbfk"
8.3.3.7 Name
方法 | 意义 | 用法 |
---|---|---|
Random.first() | 随机生成一个常见的英文名。 | Random.first() |
Random.last() | 随机生成一个常见的英文姓。 | Random.last() |
Random.name() | 随机生成一个常见的英文姓名。 | Random.name() Random.name(middle) |
Random.chineseName() | 随机生成一个常见的中文姓名。 | Random.chineseName() Random.chineseName(count) |
8.3.3.7.1 Random.first()
随机生成一个常见的英文名。
使用示例如下所示:
Random.first()
// => "Nancy"
8.3.3.7.2 Random.last()
随机生成一个常见的英文姓。
使用示例如下所示:
Random.last()
// => "Martinez"
8.3.3.7.3 Random.name()
随机生成一个常见的英文姓名。
参数的含义和默认值如下所示:
- 参数 middle:可选。布尔值。指示是否生成中间名。
使用示例如下所示:
Random.name()
// => "Larry Wilson"
Random.name(true)
// => "Helen Carol Martinez"
8.3.3.7.4 Random.chineseName()
随机生成一个常见的中文姓名。
参数的含义和默认值如下所示:
- 参数 count:可选。数字。指示姓名的字数,默认为 2 个或 3 个字的随机姓名。
使用示例如下所示:
Random.chineseName()
// => "林则徐"
Random.chineseName(2)
// => "马云"
Random.chineseName()
可以简写为Random.cname()
。从 Mock 0.2 开始,将只保留Random.cname()
。
这里只列举了我们所学的几个方法,如果还想知道完整的可以参考文档 Mock.js