学习视频:https://www.bilibili.com/video/BV1834y1676Pvd_source=1b4ebd53bacd613eec97e4a27e6457de
参考文档:微信开放文档 (qq.com)
代码构成
- 项目根目录中的
project.config.json
和project.private.config.json
文件可以对项目进行配置, project.private.config.json
中的相同设置优先级高于project.config.json
- 可以在
project.config.json
文件中配置公共的配置,在project.private.config.json
配置个人的配置,可以将project.private.config.json
写到.gitignore
避免版本管理的冲突。 project.private.config.json
中有的字段,开发者工具内的设置修改会优先覆盖project.private.config.json
的内容。如在project.private.config.json
有appid
字段,那么在 详情-基本信息 中修改了 appid,会写到project.private.config.json
中,不会覆盖掉project.config.json
的appid
字段的内容- 开发阶段相关的设置修改优先同步到
project.private.config.json
中,但与最终编译产物有关的设置无法在project.private.config.json
中生效,界面上的改动也不会同步到project.private.config.json
文件中。详见 表格 是否允许私有设置。
WXML 与 HTML 的区别
组件
除以上种类还有 1、Skyline 手势系统 2、XR-FRAME SR/3D应用解决方案 慎用 3、原生组件
4、导航栏 5、页面属性配置节点
API
分为
1、基础:系统 更新 生命周期 应用级 调试 性能 分包加载 加密
2、路由 3、跳转 4、转发
5、界面:交互 导航栏 背景 Tab-Bar 字体 下拉刷新 滚动 动画 置顶 自定义组件 菜单 窗口 worklet-动画
6、网络:请求 下载 上传 WebSocket mDNS TCP通信 UDP通信
7、支付 8、数据缓存 9、数据分析 10、XR-FRAME 11、画布
12、媒体: 地图 图片 视频 音频 背景音频 实时音视频 录音 相机 富文本 音视频合成 实时语音 画面录制器 视频解码器
13、位置 14、文件
15、开放接口: 登录 账号信息 用户信息 授权 设置 收获地址 卡券 发票 生物认证 微信运动 订阅消息 微信红包 收藏 我的小程序 车牌 视频号 音视频通话 微信群 隐私信息授权 微信客服 微信表情
16、设备:蓝牙** **低功耗中心设备 **低功耗外围设备 **信标 NFC读写 Wi-Fi 日历 联系人 无障碍
电量 剪贴板 NFC-主机卡模拟 网络 加密 屏幕 键盘 电话 加速计 罗盘 设备方向 陀螺仪 内存 扫码 短信 振动
17、AI :AI推理 视觉算法 人脸检测
18、WorKer 19、WXML 20、第三方平台 21、广告 22、SKyline
WXML语法
数据绑定
<!--wxml-->
<view> {{message}} </view>
// page.js
Page({
data: {
message: 'Hello MINA!'
}
})
列表渲染
<!--wxml-->
<view wx:for="{{array}}"> {{item}} </view>
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5]
}
})
条件渲染
<!--wxml-->
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
// page.js
Page({
data: {
view: 'MINA'
}
})
模板
<!--wxml-->
<template name="staffName">
<view>
FirstName: {{firstName}}, LastName: {{lastName}}
</view>
</template>
<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>
// page.js
Page({
data: {
staffA: {firstName: 'Hulk', lastName: 'Hu'},
staffB: {firstName: 'Shang', lastName: 'You'},
staffC: {firstName: 'Gideon', lastName: 'Lin'}
}
})
数据绑定
简单绑定
数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于:
内容
<view> {{ message }} </view>
Page({
data: {
message: 'Hello MINA!'
}
})
组件属性(需要在双引号之内)
<view id="item-{{id}}"> </view>
Page({
data: {
id: 0
}
})
控制属性(需要在双引号之内)
<view wx:if="{{condition}}"> </view>
Page({
data: {
condition: true
}
})
关键字(需要在双引号之内)
true:boolean 类型的 true,代表真值。
false: boolean 类型的 false,代表假值。
<checkbox checked="{{false}}"> </checkbox>
特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值。
运算
可以在 {{}} 内进行简单的运算,支持的有如下几种方式:
三元运算
<view hidden="{{flag ? true : false}}"> Hidden </view>
算数运算
<view> {{a + b}} + {{c}} + d </view>
Page({
data: {
a: 1,
b: 2,
c: 3
}
})
view中的内容为 3 + 3 + d。
逻辑判断
<view wx:if="{{length > 5}}"> </view>
字符串运算
<view>{{"hello" + name}}</view>
Page({
data:{
name: 'MINA'
}
})
数据路径运算
<view>{{object.key}} {{array[0]}}</view>
Page({
data: {
object: {
key: 'Hello '
},
array: ['MINA']
}
})
组合
也可以在 Mustache 内直接进行组合,构成新的对象或者数组。
数组
<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
Page({
data: {
zero: 0
}
})
最终组合成数组[0, 1, 2, 3, 4]。
对象
<template is="objectCombine" data="{{for: a, bar: b}}"></template>
Page({
data: {
a: 1,
b: 2
}
})
最终组合成的对象是 {for: 1, bar: 2}
也可以用扩展运算符 ... 来将一个对象展开
<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}。
注意: 花括号和引号之间如果有空格,将最终被解析成为字符串
<view wx:for="{{[1,2,3]}} ">
{{item}}
</view>
等同于
<view wx:for="{{[1,2,3] + ' '}}">
{{item}}
</view>
列表渲染
wx:for
在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
Page({
data: {
array: [{
message: 'foo',
}, {
message: 'bar'
}]
}
})
使用 wx:for-item 可以指定数组当前元素的变量名,
使用 wx:for-index 可以指定数组当前下标的变量名:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
wx:for 也可以嵌套,下边是一个九九乘法表
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i">
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j">
<view wx:if="{{i <= j}}">
{{i}} * {{j}} = {{i * j}}
</view>
</view>
</view>
block wx:for
类似 block wx:if,也可以将 wx:for 用在<block/>标签上,以渲染一个包含多节点的结构块。例如:
<block wx:for="{{[1, 2, 3]}}">
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
wx:key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。
wx:key 的值以两种形式提供
1、字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
2、保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
示例代码
<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch>
<button bindtap="switch"> Switch </button>
<button bindtap="addToFront"> Add to the front </button>
<switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;"> {{item}} </switch>
<button bindtap="addNumberToFront"> Add to the front </button>
Page({
data: {
objectArray: [
{id: 5, unique: 'unique_5'},
{id: 4, unique: 'unique_4'},
{id: 3, unique: 'unique_3'},
{id: 2, unique: 'unique_2'},
{id: 1, unique: 'unique_1'},
{id: 0, unique: 'unique_0'},
],
numberArray: [1, 2, 3, 4]
},
switch: function(e) {
const length = this.data.objectArray.length
for (let i = 0; i < length; ++i) {
const x = Math.floor(Math.random() * length)
const y = Math.floor(Math.random() * length)
const temp = this.data.objectArray[x]
this.data.objectArray[x] = this.data.objectArray[y]
this.data.objectArray[y] = temp
}
this.setData({
objectArray: this.data.objectArray
})
},
addToFront: function(e) {
const length = this.data.objectArray.length
this.data.objectArray = [{id: length, unique: 'unique_' + length}].concat(this.data.objectArray)
this.setData({
objectArray: this.data.objectArray
})
},
addNumberToFront: function(e){
this.data.numberArray = [ this.data.numberArray.length + 1 ].concat(this.data.numberArray)
this.setData({
numberArray: this.data.numberArray
})
}
})
注意事项
当 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>
条件渲染
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>
block wx:if
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/> 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
注意: <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
wx:if vs hidden
因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
wxss
样式导入
使用@import
语句可以导入外联样式表,@import
后跟需要导入的外联样式表的相对路径,用;
表示语句结束。
示例代码:
/** common.wxss **/
.small-p {
padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {
padding:15px;
}
内联样式
框架组件上支持使用 style、class 属性来控制组件的样式。
- style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。
<view style="color:{{color}};" />
- class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上
.
,样式类名之间用空格分隔。
<view class="normal_view" />
选择器
目前支持的选择器有:
选择器 | 样例 | 样例描述 |
---|---|---|
.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 组件前边插入内容 |
全局样式与局部样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。
WXS
WXS(WeiXin Script)是内联在 WXML 中的脚本段。通过 WXS 可以在模版中内联少量处理脚本,丰富模板的数据预处理能力。另外, WXS 还可以用来编写简单的 WXS 事件响应函数。
从语法上看, WXS 类似于有少量限制的 JavaScript WXS 语法参考 / 介绍 (qq.com)
wxs脚本 基础语法
wxs 特点
wxs不是javascript 借鉴不少,但本质区别很大
事件
除 bind
外,也可以用 catch
来绑定事件。与 bind
不同, catch
会阻止事件向上冒泡。
自基础库版本 2.8.2 起,除 bind
和 catch
外,还可以使用 mut-bind
来绑定事件。一个 mut-bind
触发后,如果事件冒泡到其他节点上,其他节点上的 mut-bind
绑定函数不会被触发,但 bind
绑定函数和 catch
绑定函数依旧会被触发。
换而言之,所有 mut-bind
是“互斥”的,只会有其中一个绑定函数被触发。同时,它完全不影响 bind
和 catch
的绑定效果。
事件对象
CustomEvent 自定义事件对象属性列表(继承 BaseEvent):
属性 | 类型 | 说明 |
---|---|---|
detail | Object | 额外的信息 |
TouchEvent 触摸事件对象属性列表(继承 BaseEvent):
属性 | 类型 | 说明 |
---|---|---|
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
特殊事件: canvas 中的触摸事件不可冒泡,所以没有 currentTarget。
使用WXS函数响应事件
基础库 2.4.4 开始支持,低版本需做兼容处理。
从基础库版本2.4.4
开始,支持使用WXS函数绑定事件,WXS函数接受2个参数,第一个是event,在原有的event的基础上加了event.instance
对象,第二个参数是ownerInstance
,和event.instance
一样是一个ComponentDescriptor
对象。具体使用如下:
- 在组件中绑定和注册事件处理的WXS函数。
<wxs module="wxs" src="./test.wxs"></wxs>
<view id="tapTest" data-hi="Weixin" bindtap="{{wxs.tapName}}"> Click me! </view>
**注:绑定的WXS函数必须用{{}}括起来**
- test.wxs文件实现tapName函数
function tapName(event, ownerInstance) {
console.log('tap Weixin', JSON.stringify(event))
}
module.exports = {
tapName: tapName
}
ownerInstance
包含了一些方法,可以设置组件的样式和class,具体包含的方法以及为什么要用WXS函数响应事件,请点击查看详情
数据绑定
在 WXML 中,普通的属性的绑定是单向的。例如:
<input value="{{value}}" />
如果使用 this.setData({ value: 'leaf' })
来更新 value
,this.data.value
和输入框的中显示的值都会被更新为 leaf
;但如果用户修改了输入框里的值,却不会同时改变 this.data.value
。
如果需要在用户输入的同时改变 this.data.value
,需要借助简易双向绑定机制。此时,可以在对应项目之前加入 model:
前缀:
<input model:value="{{value}}" />
这样,如果输入框的值被改变了, this.data.value
也会同时改变。同时, WXML 中所有绑定了 value
的位置也会被一同更新, 数据监听器 也会被正常触发。
用于双向绑定的表达式有如下限制:
1、只能是一个单一字段的绑定,如
<input model:value="值为 {{value}}" />
<input model:value="{{ a + b }}" />
都是非法的;
2、目前,尚不能 data 路径,如
<input model:value="{{ a.b }}" />
事件传参
全局配置
导航栏
上拉触底
tabBar
响应显示区域变化
小程序框架 / 视图层 / 响应显示区域变化 (qq.com)
显示区域指小程序界面中可以自由布局展示的区域。在默认情况下,小程序显示区域的尺寸自页面初始化起就不会发生变化。但以下三种方式都可以改变这一默认行为。
启用屏幕旋转支持
从小程序基础库版本 2.4.0 开始,小程序在手机上支持屏幕旋转。使小程序中的页面支持屏幕旋转的方法是:在 app.json
的 window
段中设置 "pageOrientation": "auto"
,或在页面 json 文件中配置 "pageOrientation": "auto"
。
以下是在单个页面 json 文件中启用屏幕旋转的示例。
代码示例:
{
"pageOrientation": "auto"
}
如果页面添加了上述声明,则在屏幕旋转时,这个页面将随之旋转,显示区域尺寸也会随着屏幕旋转而变化。
从小程序基础库版本 2.5.0 开始, pageOrientation
还可以被设置为 landscape
,表示固定为横屏显示。
从小程序基础库版本 2.3.0 开始,在 iPad 上运行的小程序可以支持屏幕旋转。使小程序支持 iPad 屏幕旋转的方法是:在 app.json
中添加 "resizable": true
。
从小程序基础库版本 2.21.3 开始,在 Windows、Mac、车机、安卓 WMPF 等大屏设备上运行的小程序可以支持大屏模式。可参考小程序大屏适配指南。方法是:在 app.json
中添加 "resizable": true
。
Media Query
有时,对于不同尺寸的显示区域,页面的布局会有所差异。此时可以使用 media query 来解决大多数问题。
代码示例:
.my-class {
width: 40px;
}
@media (min-width: 480px) {
/* 仅在 480px 或更宽的屏幕上生效的样式规则 */
.my-class {
width: 200px;
}
}
在 WXML 中,可以使用 match-media 组件来根据 media query 匹配状态展示、隐藏节点。
此外,可以在页面或者自定义组件 JS 中使用 this.createMediaQueryObserver()
方法来创建一个 MediaQueryObserver 对象,用于监听指定的 media query 的匹配状态。
分栏模式
在 PC 等能够以较大屏幕显示小程序的环境下,小程序支持以分栏模式展示。分栏模式可以将微信窗口分为左右两半,各展示一个页面。
目前, Windows 微信 3.3 以上版本支持分栏模式。对于其他版本微信,分栏模式不会生效。
启用分栏模式
在 app.json 中同时添加 "resizable": true
和 "frameset": true
两个配置项就可以启用分栏模式。
代码示例:
{
"resizable": true,
"frameset": true
}
启用分栏模式后,可以使用开发者工具的自动预览功能来预览分栏效果。
分栏占位图片
当某一栏没有展示任何页面时,会展示一张图片在此栏正中央。
如果代码包中的 frameset/placeholder.png
文件存在,这张图片将作为此时展示的图片。
初始渲染缓存
初始渲染缓存工作原理
小程序页面的初始化分为两个部分。
- 逻辑层初始化:载入必需的小程序代码、初始化页面 this 对象(也包括它涉及到的所有自定义组件的 this 对象)、将相关数据发送给视图层。
- 视图层初始化:载入必需的小程序代码,然后等待逻辑层初始化完毕并接收逻辑层发送的数据,最后渲染页面。
在启动页面时,尤其是小程序冷启动、进入第一个页面时,逻辑层初始化的时间较长。在页面初始化过程中,用户将看到小程序的标准载入画面(冷启动时)或可能看到轻微的白屏现象(页面跳转过程中)。
启用初始渲染缓存,可以使视图层不需要等待逻辑层初始化完毕,而直接提前将页面初始 data 的渲染结果展示给用户,这可以使得页面对用户可见的时间大大提前。它的工作原理如下:
- 在小程序页面第一次被打开后,将页面初始数据渲染结果记录下来,写入一个持久化的缓存区域(缓存可长时间保留,但可能因为小程序更新、基础库更新、储存空间回收等原因被清除);
- 在这个页面被第二次打开时,检查缓存中是否还存有这个页面上一次初始数据的渲染结果,如果有,就直接将渲染结果展示出来;
- 如果展示了缓存中的渲染结果,这个页面暂时还不能响应用户事件,等到逻辑层初始化完毕后才能响应用户事件。
利用初始渲染缓存,可以:
- 快速展示出页面中永远不会变的部分,如导航栏;
- 预先展示一个骨架页,提升用户体验;
- 展示自定义的加载提示;
- 提前展示广告,等等。
支持的组件
在初始渲染缓存阶段中,复杂组件不能被展示或不能响应交互。
目前支持的内置组件:
<view />
<text />
<button />
<image />
<scroll-view />
<rich-text />
自定义组件本身可以被展示(但它们里面用到的内置组件也遵循上述限制)
静态初始渲染缓存
若想启用初始渲染缓存,最简单的方法是在页面的 json
文件中添加配置项 "initialRenderingCache": "static"
:
{
"initialRenderingCache": "static"
}
如果想要对所有页面启用,可以在 app.json
的 window
配置段中添加这个配置:
{
"window": {
"initialRenderingCache": "static"
}
}
添加这个配置项之后,在手机中预览小程序首页,然后杀死小程序再次进入,就会通过初始渲染缓存来渲染首页。
注意:这种情况下,初始渲染缓存记录的是页面 data 应用在页面 WXML 上的结果,不包含任何 setData 的结果。
例如,如果想要在页面中展示出“正在加载”几个字,这几个字受到 loading
数据字段控制:
<view wx:if="{{loading}}">正在加载</view>
这种情况下, loading
应当在 data
中指定为 true
,如:
// 正确的做法
Page({
data: {
loading: true
}
})
而不能通过 setData
将 loading
置为 true
:
// 错误的做法!不要这么做!
Page({
data: {},
onLoad: function() {
this.setData({
loading: true
})
}
})
换而言之,这种做法只包含页面 data
的渲染结果,即页面的纯静态成分。
在初始渲染缓存中添加动态内容
有些场景中,只是页面 data
的渲染结果会比较局限。有时会想要额外展示一些可变的内容,如展示的广告图片 URL 等。
这种情况下可以使用“动态”初始渲染缓存的方式。首先,配置 "initialRenderingCache": "dynamic"
:
{
"initialRenderingCache": "dynamic"
}
此时,初始渲染缓存不会被自动启用,还需要在页面中调用 this.setInitialRenderingCache(dynamicData)
才能启用。其中, dynamicData
是一组数据,与 data
一起参与页面 WXML 渲染。
Page({
data: {
loading: true
},
onReady: function() {
this.setInitialRenderingCache({
loadingHint: '正在加载' // 这一部分数据将被应用于界面上,相当于在初始 data 基础上额外进行一次 setData
})
}
})
<view wx:if="{{loading}}">{{loadingHint}}</view>
从原理上说,在动态生成初始渲染缓存的方式下,页面会在后台使用动态数据重新渲染一次,因而开销相对较大。因而要尽量避免频繁调用 this.setInitialRenderingCache
,如果在一个页面内多次调用,仅最后一次调用生效。
注意:
this.setInitialRenderingCache
调用时机不能早于Page
的onReady
或Component
的ready
生命周期,否则可能对性能有负面影响。- 如果想禁用初始渲染缓存,调用
this.setInitialRenderingCache(null)
。
网络数据请求
视图与逻辑 导航
自定义编译
方便编译
生命周期
//index.js
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// 页面创建时执行
},
onShow: function() {
// 页面出现在前台时执行
},
onReady: function() {
// 页面首次渲染完毕时执行
},
onHide: function() {
// 页面从前台变为后台时执行
},
onUnload: function() {
// 页面销毁时执行
},
onPullDownRefresh: function() {
// 触发下拉刷新时执行
},
onReachBottom: function() {
// 页面触底时执行
},
onShareAppMessage: function () {
// 页面被用户分享时执行
},
onPageScroll: function() {
// 页面滚动时执行
},
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'
}
})
组件生命周期
自定义组件
自定义样式
组件数据 属性 方法
数据监听器
纯数据字段
插槽
组件间通信
父子
组件间
全局数据共享
npm 使用情况
首先包初始化npm init -y
css自定义属性使用 CSS 自定义属性(变量) - CSS:层叠样式表 | MDN (mozilla.org)