文章目录
- 一、全局配置
-
- 配置项
-
- 1、pages
- 2、window
- 3、tabBar
-
- 3.1:list的属性
- 二、页面配置 page.json
-
- 配置项
-
- 配置示例
- 三、sitemap 配置
-
- 配置项
-
- rules
- 配置示例
- WXML语法
- 四、数据绑定
-
- 1、简单绑定
-
- 1.1、内容
- 1.2、组件属性需要在双引号之内)
- 1.3、控制属性需要在双引号之内)
- 1.4、关键字需要在双引号之内)
- 2、运算
-
- 2.1、三元运算
- 2.2、算数运算
- 2.3、逻辑判断
- 2.4、字符串运算
- 2.5、数据路径运算
- 3、组合
-
- 3.1、数组
- 3.2、对象
- 五、列表渲染
-
-
- 1、wx:for
- 2、block wx:for
- 3、wx:key
-
- 六、条件渲染
-
-
- 1、wx:if
- 2、hidden
- 3、block wx:if
- 4、wx:if` vs `hidden
-
- 七、模板
-
-
- 1、定义模板
- 2、使用模板
- 4、模板的作用域
-
- 八、引用
-
-
- 1、import
- 2、import 的作用域
- 3、include
-
- 九、事件
-
- 1、什么是事件
- 2、事件的使用方式
- 3、使用WXS函数响应事件
- 4、事件详解
-
- 4.1、事件分类
- 4.2、普通事件绑定
- 4.3、绑定并阻止事件冒泡
- 互斥事件绑定
- 4.4、事件的捕获阶段
- 4.事件对象
- type
- timeStamp
- target
- currentTarget
- dataset
- mark
- touches
-
- Touch 对象
- CanvasTouch 对象
- changedTouches
- detail
- 5、简易双向绑定
-
- 5.1、双向绑定语法
- 5.2、在自定义组件中传递双向绑定
- 5.3、在自定义组件中触发双向绑定更新
- 6、特别注意
- 十、常用组件
-
- 1、button
-
- 1.1、示例代码
- 2、input
-
- 2.1、示例代码
- 3、form
-
- 3.1、示例代码
- 3.2、使用内置 behaviors
- 3.3、wx://form-field
- 3.4、wx://form-field-group
- 3.5、wx://form-field-button
- 4、view 视图容器
-
- 4.1、示例代码
- 5、text 文本
-
- 5.1、示例代码
- 6、image
-
- 6.1、Bug & Tip
- 6.2、示例代码
- 7、swiper(轮播图)
-
- `7.1、change`事件 `source` 返回值
- 7.2、Bug & Tip
- 7.3、示例代码
- 8、navigator 导航组件类似超链接标签)
-
- 8.1、使用限制
- 8.2、关于调试
- 8.3、Bug & Tip
- 8.4、示例代码
- 9、rich-text(富文本标签)
-
- 9.1、nodes
- 9.2、受信任的HTML节点及属性
- 9.4、Bug & Tip
- 9.5、示例代码
- 10、icon(图标)
-
- 10.1、示例代码
- 11、radio-group
- 12、radio(单选)
-
- 12.1、示例代码
- 13、checkbox-group
- 14、checkbox(复选框)
-
- 示例代码
- 十 一、wxss语法
-
-
- 1、尺寸单位
- 2、样式导入
- 3、内联样式
- 4、选择器
- 5、全局样式与局部样式
-
- 十二、自定义组件
-
-
- 1、创建自定义组件
- 2、使用自定义组件
- 3、细节注意事项
- 4、组件间通信与事件(父子组件相互传递)
-
- 4.1、组件间通信
- 4.2、监听事件
- 4.3、触发事件
- 4.4、获取组件实例
- 5、Component 构造器
-
- 5.1、使用 Component 构造器构造页面
- 6、小程序常用自定义属性
- 十三、小程序的生命周期
-
- 1、应用生命周期
- 2、页面生命周期
- 3、页面生命周期流程图
-
一、全局配置
小程序根目录下的 app.json
文件用来对微信小程序进行全局配置。文件内容为一个 JSON 对象,有以下属性:
配置项
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
pages | string[] | 是 | 页面路径列表 |
window | Object | 否 | 全局的默认窗口表现 |
tabBar | Object | 否 | 底部 tab 栏的表现 |
networkTimeout | Object | 否 | 网络超时时间 |
debug | boolean | 否 | 是否开启 debug 模式,默认关闭 |
functionalPages | boolean | 否 | 是否启用插件功能页,默认关闭 |
subpackages | Object[] | 否 | 分包结构配置 |
workers | string | 否 | Worker 代码放置的目录 |
requiredBackgroundModes | string[] | 否 | 需要在后台使用的能力,如「音乐播放」 |
plugins | Object | 否 | 使用到的插件 |
preloadRule | Object | 否 | 分包预下载规则 |
resizable | boolean | 否 | PC 小程序是否支持用户任意改变窗口大小(包括最大化窗口);iPad 小程序是否支持屏幕旋转。默认关闭 |
usingComponents | Object | 否 | 全局自定义组件配置 |
permission | Object | 否 | 小程序接口权限相关设置 |
sitemapLocation | string | 是 | 指明 sitemap.json 的位置 |
style | string | 否 | 指定使用升级后的weui样式 |
useExtendedLib | Object | 否 | 指定需要引用的扩展库 |
entranceDeclare | Object | 否 | 微信消息用小程序打开 |
darkmode | boolean | 否 | 小程序支持 DarkMode |
themeLocation | string | 否 | 指明 theme.json 的位置,darkmode为true为必填 |
1、pages
用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径(含文件名) 信息。文件名不需要写文件后缀,框架会自动去寻找对应位置的 .json
, .js
, .wxml
, .wxss
四个文件进行处理。
数组的第一项代表小程序的初始页面(首页)。小程序中新增/减少页面,都需要对 pages 数组进行修改。
如开发目录为:
├── app.js
├── app.json
├── app.wxss
├── pages
│ │── index
│ │ ├── index.wxml
│ │ ├── index.js
│ │ ├── index.json
│ │ └── index.wxss
│ └── logs
│ ├── logs.wxml
│ └── logs.js
└── utils
2、window
用于设置小程序的状态栏、导航条、标题、窗口背景色。
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色,如 #000000 |
navigationBarTextStyle | string | white | 导航栏标题颜色,仅支持 black / white |
navigationBarTitleText | string | 导航栏标题文字内容 | |
navigationStyle | string | default | 导航栏样式,仅支持以下值: default 默认样式 custom 自定义导航栏,只保留右上角胶囊按钮。参见注 2。 |
backgroundColor | HexColor | #ffffff | 窗口的背景色 |
backgroundTextStyle | string | dark | 下拉 loading 的样式,仅支持 dark / light |
backgroundColorTop | string | #ffffff | 顶部窗口的背景色,仅 iOS 支持 |
backgroundColorBottom | string | #ffffff | 底部窗口的背景色,仅 iOS 支持 |
enablePullDownRefresh | boolean | false | 是否开启全局的下拉刷新。 详见 Page.onPullDownRefresh |
onReachBottomDistance | number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为 px。 详见 Page.onReachBottom |
pageOrientation | string | portrait | 屏幕旋转设置,支持 auto / portrait / landscape 详见 响应显示区域变化 |
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,见详情 |
3.1:list的属性
其中 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。 |
二、页面配置 page.json
每一个小程序页面也可以使用 .json
文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖 app.json
的 window
中相同的配置项。文件内容为一个 JSON 对象,有以下属性:
配置项
属性 | 类型 | 默认值 | 描述 | 最低版本 |
---|---|---|---|---|
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色,如 #000000 |
|
navigationBarTextStyle | string | white | 导航栏标题颜色,仅支持 black / white |
|
navigationBarTitleText | string | 导航栏标题文字内容 | ||
navigationStyle | string | default | 导航栏样式,仅支持以下值: default 默认样式 custom 自定义导航栏,只保留右上角胶囊按钮 |
微信客户端 7.0.0 |
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) |
disableScroll | boolean | false | 设置为 true 则页面整体不能上下滚动。 只在页面配置中有效,无法在 app.json 中设置 |
|
usingComponents | Object | 否 | 页面自定义组件配置 | 1.6.3 |
style | string | default | 启用新版的组件样式 | 2.10.2 |
页面配置中只能设置
app.json
中window
对应的配置项,以决定本页面的窗口表现,所以无需写window
这个属性。
配置示例
{"navigationBarBackgroundColor": "#ffffff","navigationBarTextStyle": "black","navigationBarTitleText": "微信接口功能演示","backgroundColor": "#eeeeee","backgroundTextStyle": "light"
}
三、sitemap 配置
小程序根目录下的 sitemap.json
文件用于配置小程序及其页面是否允许被微信索引,文件内容为一个 JSON 对象,如果没有 sitemap.json
,则默认为所有页面都允许被索引;sitemap.json
有以下属性:
配置项
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
rules | Object[] | 是 | 索引规则列表 |
rules
rules 配置项指定了索引规则,每项规则为一个JSON对象,属性如下所示:
属性 | 类型 | 必填 | 默认值 | 取值 | 取值说明 |
---|---|---|---|---|---|
action | string | 否 | “allow” | “allow”、“disallow” | 命中该规则的页面是否能被索引 |
page | string | 是 | “*”、页面的路径 | * 表示所有页面,不能作为通配符使用 |
|
params | string[] | 否 | [] | 当 page 字段指定的页面在被本规则匹配时可能使用的页面参数名称的列表(不含参数值) | |
matching | string | 否 | “inclusive” | 参考 matching 取值说明 | 当 page 字段指定的页面在被本规则匹配时,此参数说明 params 匹配方式 |
priority | Number | 否 | 优先级,值越大则规则越早被匹配,否则默认从上到下匹配 |
matching 取值说明
值 | 说明 |
---|---|
exact | 当小程序页面的参数列表等于 params 时,规则命中 |
inclusive | 当小程序页面的参数列表包含 params 时,规则命中 |
exclusive | 当小程序页面的参数列表与 params 交集为空时,规则命中 |
partial | 当小程序页面的参数列表与 params 交集不为空时,规则命中 |
配置示例
示例1
{"rules":[{"action": "allow","page": "path/to/page","params": ["a", "b"],"matching": "exact"}, {"action": "disallow","page": "path/to/page"}]
}
path/to/page?a=1&b=2
=> 优先索引path/to/page
=> 不被索引path/to/page?a=1
=> 不被索引path/to/page?a=1&b=2&c=3
=> 不被索引- 其他页面都会被索引
示例2
{"rules":[{"action": "allow","page": "path/to/page","params": ["a", "b"],"matching": "inclusive"}, {"action": "disallow","page": "path/to/page"}]
}
path/to/page?a=1&b=2
=> 优先索引path/to/page?a=1&b=2&c=3
=> 优先索引path/to/page
=> 不被索引path/to/page?a=1
=> 不被索引- 其他页面都会被索引
示例3
{"rules":[{"action": "allow","page": "path/to/page","params": ["a", "b"],"matching": "exclusive"}, {"action": "disallow","page": "path/to/page"}]
}
path/to/page
=> 优先索引path/to/page?c=3
=> 优先索引path/to/page?a=1
=> 不被索引path/to/page?a=1&b=2
=> 不被索引- 其他页面都会被索引
示例4
{"rules":[{"action": "allow","page": "path/to/page","params": ["a", "b"],"matching": "partial"}, {"action": "disallow","page": "path/to/page"}]
}
path/to/page?a=1
=> 优先索引path/to/page?a=1&b=2
=> 优先索引path/to/page
=> 不被索引path/to/page?c=3
=> 不被索引- 其他页面都会被索引
注:没有 sitemap.json 则默认所有页面都能被索引
注:{"action": "allow", "page": "\*"}
是优先级最低的默认规则,未显式指明 “disallow” 的都默认被索引
WXML语法
四、数据绑定
WXML中的动态数据均来自对应 Page 的 data。
1、简单绑定
数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于:
1.1、内容
<!-- text 相当于html中的行内标签:space标签view 相当于htnl中的块标签: div标签
-->
<view> {{ message }} </view>
Page{data: {message: 'Hello MINA!'}
})
1.2、组件属性需要在双引号之内)
<view id="item-{{id}}"> </view>
Page{data: {id: 0}
})
1.3、控制属性需要在双引号之内)
<view wx:if="{{condition}}"> </view>
Page{data: {condition: true}
})
1.4、关键字需要在双引号之内)
true
:boolean 类型的 true,代表真值。
false
: boolean 类型的 false,代表假值。
<checkbox checked="{{false}}"> </checkbox>
特别注意:不要直接写 checked="false"
,其计算结果是一个字符串,转成 boolean 类型后代表真值。
2、运算
可以在 {{}}
内进行简单的运算,支持的有如下几种方式:
2.1、三元运算
<view hidden="{{flag ? true : false}}"> Hidden </view>
2.2、算数运算
<view> {{a + b}} + {{c}} + d </view>
Page{data: {a: 1,b: 2,c: 3}
})
view中的内容为 3 + 3 + d
。
2.3、逻辑判断
<view wx:if="{{length > 5}}"> </view>
2.4、字符串运算
<view>{{"hello" + name}}</view>
Page{data:{name: 'MINA'}
})
2.5、数据路径运算
<view>{{object.key}} {{array[0]}}</view>
Page{data: {object: {key: 'Hello '},array: ['MINA']}
})
3、组合
也可以在 Mustache 内直接进行组合,构成新的对象或者数组。
3.1、数组
<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
Page{data: {zero: 0}
})
最终组合成数组[0, 1, 2, 3, 4]
。
3.2、对象
<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>
五、列表渲染
1、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>
2、block wx:for
类似 block wx:if
,也可以将 wx:for
用在<block/>
标签上,以渲染一个包含多节点的结构块。例如:
<block wx:for="{{[1, 2, 3]}}"><view> {{index}}: </view><view> {{item}} </view>
</block>
3、wx:key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用 wx:key
来指定列表中项目的唯一的标识符。
wx:key
的值以两种形式提供
- 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字
*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: functione) {const length = this.data.objectArray.lengthfor let i = 0; i < length; ++i) {const x = Math.floorMath.random) * length)const y = Math.floorMath.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: functione) {const length = this.data.objectArray.lengththis.data.objectArray = [{id: length, unique: 'unique_' + length}].concatthis.data.objectArray)this.setData{objectArray: this.data.objectArray})},addNumberToFront: functione){this.data.numberArray = [ this.data.numberArray.length + 1 ].concatthis.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>
六、条件渲染
1、wx:if
在框架中,使用 wx:if=""
来判断是否需要渲染该代码块:
<view wx:if="{{condition}}"> True </view>
也可以用 wx:elif
和 wx:else
来添加一个 else 块:
<!--wx:if wx:elif wx:else 类似于if、 else if、 else-->
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
2、hidden
<!-- 1、 在标签直接加入hidden属性,隐藏标签2、hidden="{{false}}"显示标签
-->
<view hidden>隐藏</view>
<view hidden="{{false}}">显示</view>
3、block wx:if
因为 wx:if
是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/>
标签将多个组件包装起来,并在上边使用 wx:if
控制属性。
<block wx:if="{{true}}"><view> view1 </view><view> view2 </view>
</block>
注意: <block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
4、wx:ifvs
hidden
<!-- 1、当标签不是频繁切换的时候 优先使用wx:ifwx:if是直接把标签结构从页面移除掉2、 当标签频繁切换的时候 优先使用hiddenhidden属性是添加样式拉切换显示hidden不要和dispaly一起使用-->
因为 wx:if
之中的模板也可能包含数据绑定,所以当 wx:if
的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if
也是惰性的,如果在初始渲染条件为 false
,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden
就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if
有更高的切换消耗而 hidden
有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden
更好,如果在运行时条件不大可能改变则 wx:if
较好。
七、模板
WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
1、定义模板
使用 name 属性,作为模板的名字。然后在<template/>
内定义代码片段,如:
<!--index: intmsg: stringtime: string
-->
<template name="msgItem"><view><text> {{index}}: {{msg}} </text><text> Time: {{time}} </text></view>
</template>
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>
4、模板的作用域
模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的 <wxs />
模块。
八、引用
WXML 提供两种文件引用方式import
和include
。
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'}}"/>
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"/>
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>
九、事件
1、什么是事件
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
2、事件的使用方式
- 在组件中绑定一个事件处理函数。
如bindtap
,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
- 在相应的Page定义中写上相应的事件处理函数,参数是event。
Page{tapName: functionevent) {console.logevent)}
})
- 可以看到log出来的信息大致如下:
{"type":"tap","timeStamp":895,"target": {"id": "tapTest","dataset": {"hi":"WeChat"}},"currentTarget": {"id": "tapTest","dataset": {"hi":"WeChat"}},"detail": {"x":53,"y":14},"touches":[{"identifier":0,"pageX":53,"pageY":14,"clientX":53,"clientY":14}],"changedTouches":[{"identifier":0,"pageX":53,"pageY":14,"clientX":53,"clientY":14}]
}
3、使用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="WeChat" bindtap="{{wxs.tapName}}"> Click me! </view>
**注:绑定的WXS函数必须用{{}}括起来**
- test.wxs文件实现tapName函数
function tapNameevent, ownerInstance) {console.log'tap wechat', JSON.stringifyevent))
}
module.exports = {tapName: tapName
}
ownerInstance
包含了一些方法,可以设置组件的样式和class,具体包含的方法以及为什么要用WXS函数响应事件,请点击查看详情。
4、事件详解
4.1、事件分类
事件分为冒泡事件和非冒泡事件:
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
WXML的冒泡事件列表:
类型 | 触发条件 | 最低版本 |
---|---|---|
touchstart | 手指触摸动作开始 | |
touchmove | 手指触摸后移动 | |
touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 | |
touchend | 手指触摸动作结束 | |
tap | 手指触摸后马上离开 | |
longpress | 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 | 1.5.0 |
longtap | 手指触摸后,超过350ms再离开(推荐使用longpress事件代替) | |
transitionend | 会在 WXSS transition 或 wx.createAnimation 动画结束后触发 | |
animationstart | 会在一个 WXSS animation 动画开始时触发 | |
animationiteration | 会在一个 WXSS animation 一次迭代结束时触发 | |
animationend | 会在一个 WXSS animation 动画完成时触发 | |
touchforcechange | 在支持 3D Touch 的 iPhone 设备,重按时会触发 | 1.9.90 |
注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的submit
事件,input 的input
事件,scroll-view 的scroll
事件,详见各个组件)
4.2、普通事件绑定
事件绑定的写法类似于组件的属性,如:
<view bindtap="handleTap">Click here!
</view>
如果用户点击这个 view ,则页面的 handleTap
会被调用。
事件绑定函数可以是一个数据绑定,如:
<view bindtap="{{ handlerName }}">Click here!
</view>
此时,页面的 this.data.handlerName
必须是一个字符串,指定事件处理函数名;如果它是个空字符串,则这个绑定会失效(可以利用这个特性来暂时禁用一些事件)。
自基础库版本 1.5.0 起,在大多数组件和自定义组件中, bind
后可以紧跟一个冒号,其含义不变,如 bind:tap
。基础库版本 2.8.1 起,在所有组件中开始提供这个支持。
4.3、绑定并阻止事件冒泡
除 bind
外,也可以用 catch
来绑定事件。与 bind
不同, catch
会阻止事件向上冒泡。
例如在下边这个例子中,点击 inner view 会先后调用handleTap3
和handleTap2
因为tap事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),点击 middle view 会触发handleTap2
,点击 outer view 会触发handleTap1
。
<view id="outer" bindtap="handleTap1">outer view<view id="middle" catchtap="handleTap2">middle view<view id="inner" bindtap="handleTap3">inner view</view></view>
</view>
互斥事件绑定
自基础库版本 2.8.2 起,除 bind
和 catch
外,还可以使用 mut-bind
来绑定事件。一个 mut-bind
触发后,如果事件冒泡到其他节点上,其他节点上的 mut-bind
绑定函数不会被触发,但 bind
绑定函数和 catch
绑定函数依旧会被触发。
换而言之,所有 mut-bind
是“互斥”的,只会有其中一个绑定函数被触发。同时,它完全不影响 bind
和 catch
的绑定效果。
例如在下边这个例子中,点击 inner view 会先后调用 handleTap3
和 handleTap2
,点击 middle view 会调用 handleTap2
和 handleTap1
。
<view id="outer" mut-bind:tap="handleTap1">outer view<view id="middle" bindtap="handleTap2">middle view<view id="inner" mut-bind:tap="handleTap3">inner view</view></view>
</view>
4.4、事件的捕获阶段
自基础库版本 1.5.0 起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用capture-bind
、capture-catch
关键字,后者将中断捕获阶段和取消冒泡阶段。
在下面的代码中,点击 inner view 会先后调用handleTap2
、handleTap4
、handleTap3
、handleTap1
。
<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">outer view<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">inner view</view>
</view>
如果将上面代码中的第一个capture-bind
改为capture-catch
,将只触发handleTap2
。
<view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2">outer view<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">inner view</view>
</view>
4.事件对象
如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。
BaseEvent 基础事件对象属性列表:
属性 | 类型 | 说明 | 基础库版本 |
---|---|---|---|
type | String | 事件类型 | |
timeStamp | Integer | 事件生成时的时间戳 | |
target | Object | 触发事件的组件的一些属性值集合 | |
currentTarget | Object | 当前组件的一些属性值集合 | |
mark | Object | 事件标记数据 | 2.7.1 |
CustomEvent 自定义事件对象属性列表(继承 BaseEvent):
属性 | 类型 | 说明 |
---|---|---|
detail | Object | 额外的信息 |
TouchEvent 触摸事件对象属性列表(继承 BaseEvent):
属性 | 类型 | 说明 |
---|---|---|
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
特殊事件: canvas 中的触摸事件不可冒泡,所以没有 currentTarget。
type
代表事件的类型。
timeStamp
页面打开到触发事件所经过的毫秒数。
target
触发事件的源组件。
属性 | 类型 | 说明 |
---|---|---|
id | String | 事件源组件的id |
dataset | Object | 事件源组件上由data- 开头的自定义属性组成的集合 |
currentTarget
事件绑定的当前组件。
属性 | 类型 | 说明 |
---|---|---|
id | String | 当前组件的id |
dataset | Object | 当前组件上由data- 开头的自定义属性组成的集合 |
说明: target 和 currentTarget 可以参考上例中,点击 inner view 时,handleTap3
收到的事件对象 target 和 currentTarget 都是 inner,而 handleTap2
收到的事件对象 target 就是 inner,currentTarget 就是 middle。
dataset
在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。
在 WXML 中,这些自定义数据以 data-
开头,多个单词由连字符 -
连接。这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如:
data-element-type
,最终会呈现为event.currentTarget.dataset.elementType
;data-elementType
,最终会呈现为event.currentTarget.dataset.elementtype
。
示例:
<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>
Page{bindViewTap:functionevent){event.currentTarget.dataset.alphaBeta === 1 // - 会转为驼峰写法event.currentTarget.dataset.alphabeta === 2 // 大写会转为小写}
})
mark
在基础库版本 2.7.1 以上,可以使用 mark
来识别具体触发事件的 target 节点。此外, mark
还可以用于承载一些自定义数据(类似于 dataset
)。
当事件触发时,事件冒泡路径上所有的 mark
会被合并,并返回给事件回调函数。(即使事件不是冒泡事件,也会 mark
。)
代码示例:
在开发者工具中预览效果
<view mark:myMark="last" bindtap="bindViewTap"><button mark:anotherMark="leaf" bindtap="bindButtonTap">按钮</button>
</view>
在上述 WXML 中,如果按钮被点击,将触发 bindViewTap
和 bindButtonTap
两个事件,事件携带的 event.mark
将包含 myMark
和 anotherMark
两项。
Page{bindViewTap: functione) {e.mark.myMark === "last" // truee.mark.anotherMark === "leaf" // true}
})
mark
和 dataset
很相似,主要区别在于: mark
会包含从触发事件的节点到根节点上所有的 mark:
属性值;而 dataset
仅包含一个节点的 data-
属性值。
细节注意事项:
- 如果存在同名的
mark
,父节点的mark
会被子节点覆盖。 - 在自定义组件中接收事件时,
mark
不包含自定义组件外的节点的mark
。 - 不同于
dataset
,节点的mark
不会做连字符和大小写转换。
touches
touches 是一个数组,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。
Touch 对象
属性 | 类型 | 说明 |
---|---|---|
identifier | Number | 触摸点的标识符 |
pageX, pageY | Number | 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴 |
clientX, clientY | Number | 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴 |
CanvasTouch 对象
属性 | 类型 | 说明 | 特殊说明 |
---|---|---|---|
identifier | Number | 触摸点的标识符 | |
x, y | Number | 距离 Canvas 左上角的距离,Canvas 的左上角为原点 ,横向为X轴,纵向为Y轴 |
changedTouches
changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。
detail
自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。
点击事件的detail
带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。
5、简易双向绑定
5.1、双向绑定语法
在 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
的位置也会被一同更新, 数据监听器 也会被正常触发。
在开发者工具中预览效果
用于双向绑定的表达式有如下限制:
- 只能是一个单一字段的绑定,如
<input model:value="值为 {{value}}" />
<input model:value="{{ a + b }}" />
都是非法的;
- 目前,尚不能 data 路径,如
<input model:value="{{ a.b }}" />
这样的表达式目前暂不支持。
5.2、在自定义组件中传递双向绑定
双向绑定同样可以使用在自定义组件上。如下的自定义组件:
// custom-component.js
Component{properties: {myValue: String}
})
<!-- custom-component.wxml -->
<input model:value="{{myValue}}" />
这个自定义组件将自身的 myValue
属性双向绑定到了组件内输入框的 value
属性上。这样,如果页面这样使用这个组件:
<custom-component model:my-value="{{pageValue}}" />
当输入框的值变更时,自定义组件的 myValue
属性会同时变更,这样,页面的 this.data.pageValue
也会同时变更,页面 WXML 中所有绑定了 pageValue
的位置也会被一同更新。
5.3、在自定义组件中触发双向绑定更新
自定义组件还可以自己触发双向绑定更新,做法就是:使用 setData 设置自身的属性。例如:
// custom-component.js
Component{properties: {myValue: String},methods: {update: function) {// 更新 myValuethis.setData{myValue: 'leaf'})}}
})
如果页面这样使用这个组件:
<custom-component model:my-value="{{pageValue}}" />
当组件使用 setData
更新 myValue
时,页面的 this.data.pageValue
也会同时变更,页面 WXML 中所有绑定了 pageValue
的位置也会被一同更新。
6、特别注意
1、绑定事件的时候不能带参数 不能带括号 以下为错误写法】
<button bindtap="hendtab1)">点击加1</button>
2、事件传值通过标签自定义参数 和 value的方式
<button bindtap="hendtab" data-opertion="{{1}}">+</button>
3、事件触发获取数据
参数列表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传img-zfhGC33Y-1592750284841)D:\NULL\学习资源\md笔记\images\小程序参数列表.png)]
<!-- 1、获取标签自定义属性值:e为传入的参数e.currentTarget.dataset.opertion2、给data中的初始数据重新复制:如: data: {num: 0}this.setData{num: e.detail.value})-->hanedIpute) {<!--获取文本框(input)的value值-->console.loge.detail.value);<!--获取标签自定义属性data- 的value值-->console.loge.currentTarget.dataset.opertion);}
十、常用组件
1、button
基础库 1.0.0 开始支持,低版本需做兼容处理。
按钮。
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
size | string | default | 否 | 按钮的大小 |
type | string | default | 否 | 按钮的样式类型 |
plain | boolean | false | 否 | 按钮是否镂空,背景色透明 |
disabled | boolean | false | 否 | 是否禁用 |
loading | boolean | false | 否 | 名称前是否带 loading 图标 |
form-type | string | 否 | 用于 form 组件,点击分别会触发 form 组件的 submit/reset 事件 | |
open-type | string | 否 | 微信开放能力 | |
hover-class | string | button-hover | 否 | 指定按钮按下去的样式类。当 hover-class="none" 时,没有点击态效果 |
hover-stop-propagation | boolean | false | 否 | 指定是否阻止本节点的祖先节点出现点击态 |
hover-start-time | number | 20 | 否 | 按住后多久出现点击态,单位毫秒 |
hover-stay-time | number | 70 | 否 | 手指松开后点击态保留时间,单位毫秒 |
lang | string | en | 否 | 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。 |
session-from | string | 否 | 会话来源,open-type="contact"时有效 | |
send-message-title | string | 当前标题 | 否 | 会话内消息卡片标题,open-type="contact"时有效 |
send-message-path | string | 当前分享路径 | 否 | 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效 |
send-message-img | string | 截图 | 否 | 会话内消息卡片图片,open-type="contact"时有效 |
app-parameter | string | 否 | 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 | |
show-message-card | boolean | false | 否 | 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,open-type="contact"时有效 |
bindgetuserinfo | eventhandle | 否 | 用户点击该按钮时,会返回获取到的用户信息,回调的detail数据与wx.getUserInfo返回的一致,open-type="getUserInfo"时有效 | |
bindcontact | eventhandle | 否 | 客服消息回调,open-type="contact"时有效 | |
bindgetphonenumber | eventhandle | 否 | 获取用户手机号回调,open-type=getPhoneNumber时有效 | |
binderror | eventhandle | 否 | 当使用开放能力时,发生错误的回调,open-type=launchApp时有效 | |
bindopensetting | eventhandle | 否 | 在打开授权设置页后回调,open-type=openSetting时有效 | |
bindlaunchapp | eventhandle | 否 | 打开 APP 成功的回调,open-type=launchApp时有效 |
size 的合法值
值 | 说明 | 最低版本 |
---|---|---|
default | 默认大小 | |
mini | 小尺寸 |
type 的合法值
值 | 说明 | 最低版本 |
---|---|---|
primary | 绿色 | |
default | 白色 | |
warn | 红色 |
form-type 的合法值
值 | 说明 | 最低版本 |
---|---|---|
submit | 提交表单 | |
reset | 重置表单 |
open-type 的合法值
值 | 说明 | 最低版本 |
---|---|---|
contact | 打开客服会话,如果用户在会话中点击消息卡片后返回小程序,可以从 bindcontact 回调中获得具体信息,具体说明 | 1.1.0 |
share | 触发用户转发,使用前建议先阅读使用指引 | 1.2.0 |
getPhoneNumber | 获取用户手机号,可以从bindgetphonenumber回调中获取到用户信息,具体说明 | 1.2.0 |
getUserInfo | 获取用户信息,可以从bindgetuserinfo回调中获取到用户信息 | 1.3.0 |
launchApp | 打开APP,可以通过app-parameter属性设定向APP传的参数具体说明 | 1.9.5 |
openSetting | 打开授权设置页 | 2.0.7 |
feedback | 打开“意见反馈”页面,用户可提交反馈内容并上传日志,开发者可以登录小程序管理后台后进入左侧菜单“客服反馈”页面获取到反馈内容 | 2.1.0 |
lang 的合法值
值 | 说明 | 最低版本 |
---|---|---|
en | 英文 | |
zh_CN | 简体中文 | |
zh_TW | 繁体中文 |
1.1、示例代码
在开发者工具中预览效果
2、input
基础库 1.0.0 开始支持,低版本需做兼容处理。
输入框。该组件是原生组件,使用时请注意相关限制
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
value | string | 是 | 输入框的初始内容 | 1.0.0 | |
type | string | text | 否 | input 的类型 | 1.0.0 |
password | boolean | false | 否 | 是否是密码类型 | 1.0.0 |
placeholder | string | 是 | 输入框为空时占位符 | 1.0.0 | |
placeholder-style | string | 是 | 指定 placeholder 的样式 | 1.0.0 | |
placeholder-class | string | input-placeholder | 否 | 指定 placeholder 的样式类 | 1.0.0 |
disabled | boolean | false | 否 | 是否禁用 | 1.0.0 |
maxlength | number | 140 | 否 | 最大输入长度,设置为 -1 的时候不限制最大长度 | 1.0.0 |
cursor-spacing | number | 0 | 否 | 指定光标与键盘的距离,取 input 距离底部的距离和 cursor-spacing 指定的距离的最小值作为光标与键盘的距离 | 1.0.0 |
auto-focus | boolean | false | 否 | 即将废弃,请直接使用 focus )自动聚焦,拉起键盘 | 1.0.0 |
focus | boolean | false | 否 | 获取焦点 | 1.0.0 |
confirm-type | string | done | 否 | 设置键盘右下角按钮的文字,仅在type='text’时生效 | 1.1.0 |
confirm-hold | boolean | false | 否 | 点击键盘右下角按钮时是否保持键盘不收起 | 1.1.0 |
cursor | number | 是 | 指定focus时的光标位置 | 1.5.0 | |
selection-start | number | -1 | 否 | 光标起始位置,自动聚集时有效,需与selection-end搭配使用 | 1.9.0 |
selection-end | number | -1 | 否 | 光标结束位置,自动聚集时有效,需与selection-start搭配使用 | 1.9.0 |
adjust-position | boolean | true | 否 | 键盘弹起时,是否自动上推页面 | 1.9.90 |
hold-keyboard | boolean | false | 否 | focus时,点击页面的时候不收起键盘 | 2.8.2 |
bindinput | eventhandle | 是 | 键盘输入时触发,event.detail = {value, cursor, keyCode},keyCode 为键值,2.1.0 起支持,处理函数可以直接 return 一个字符串,将替换输入框的内容。 | 1.0.0 | |
bindfocus | eventhandle | 是 | 输入框聚焦时触发,event.detail = { value, height },height 为键盘高度,在基础库 1.9.90 起支持 | 1.0.0 | |
bindblur | eventhandle | 是 | 输入框失去焦点时触发,event.detail = {value: value} | 1.0.0 | |
bindconfirm | eventhandle | 是 | 点击完成按钮时触发,event.detail = {value: value} | 1.0.0 | |
bindkeyboardheightchange | eventhandle | 是 | 键盘高度发生变化的时候触发此事件,event.detail = {height: height, duration: duration} | 2.7.0 |
type 的合法值
值 | 说明 | 最低版本 |
---|---|---|
text | 文本输入键盘 | |
number | 数字输入键盘 | |
idcard | 身份证输入键盘 | |
digit | 带小数点的数字键盘 |
confirm-type 的合法值
值 | 说明 | 最低版本 |
---|---|---|
send | 右下角按钮为“发送” | |
search | 右下角按钮为“搜索” | |
next | 右下角按钮为“下一个” | |
go | 右下角按钮为“前往” | |
done | 右下角按钮为“完成” |
2.1、示例代码
在开发者工具中预览效果
3、form
基础库 1.0.0 开始支持,低版本需做兼容处理。
表单。将组件内的用户输入的switch input checkbox slider radio picker 提交。
当点击 form 表单中 form-type 为 submit 的 button 组件时,会将表单组件中的 value 值进行提交,需要在表单组件中加上 name 来作为 key。
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
report-submit | boolean | false | 否 | 是否返回 formId 用于发送模板消息 | 1.0.0 |
report-submit-timeout | number | 0 | 否 | 等待一段时间(毫秒数)以确认 formId 是否生效。如果未指定这个参数,formId 有很小的概率是无效的(如遇到网络失败的情况)。指定这个参数将可以检测 formId 是否有效,以这个参数的时间作为这项检测的超时时间。如果失败,将返回 requestFormId:fail 开头的 formId | 2.6.2 |
bindsubmit | eventhandle | 否 | 携带 form 中的数据触发 submit 事件,event.detail = {value : {‘name’: ‘value’} , formId: ‘’} | 1.0.0 | |
bindreset | eventhandle | 否 | 表单重置时会触发 reset 事件 | 1.0.0 |
3.1、示例代码
// 在开发者工具中预览效果
3.2、使用内置 behaviors
对于 form 组件,目前可以自动识别下列内置 behaviors:
wx://form-field
wx://form-field-group
wx://form-field-button
3.3、wx://form-field
使自定义组件有类似于表单控件的行为。 form 组件可以识别这些自定义组件,并在 submit 事件中返回组件的字段名及其对应字段值。这将为它添加以下两个属性。
属性名 | 类型 | 描述 | 最低版本 |
---|---|---|---|
name | String | 在表单中的字段名 | 1.6.7 |
value | 任意 | 在表单中的字段值 | 1.6.7 |
代码示例: 在开发者工具中预览效果
// custom-form-field.js
Component{behaviors: ['wx://form-field'],data: {value: ''},methods: {onChange: function e) {this.setData{value: e.detail.value,})}}
})
3.4、wx://form-field-group
从基础库版本 2.10.2 开始提供支持。
代码示例: 在开发者工具中预览效果
使 form 组件可以识别到这个自定义组件内部的所有表单控件。 例如,页面的结构如下:
<form bindsubmit="submit"><custom-comp></custom-comp><button form-type="submit">submit</button>
</form>
组件 custom-comp
自身结构如下:
<input name="name" />
<switch name="student" />
如果组件 custom-comp
配置有:
Component{behaviors: ['wx://form-field-group']
})
此时,表单的 submit
事件的 value
中将包含 name
和 student
两个字段。
3.5、wx://form-field-button
从基础库版本 2.10.3 开始提供支持。
代码示例: 在开发者工具中预览效果
使 form 组件可以识别到这个自定义组件内部的 button , 如果自定义组件内部有设置了 form-type 的 button ,它将被组件外的 form 接受。 例如,页面的结构如下:
<form bindsubmit="submit"><input name="name" placeholder="请输入名字"></input><custom-comp></custom-comp>
</form>
组件 custom-comp
自身结构如下:
<button form-type="submit">submit</button>
如果组件 custom-comp
配置有:
Component{behaviors: ['wx://form-field-button']
})
此时点击组件内的 button ,将触发 form 的 submit 事件。
4、view 视图容器
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
hover-class | string | none | 否 | 指定按下去的样式类。当 hover-class="none" 时,没有点击态效果 |
hover-stop-propagation | boolean | false | 否 | 指定是否阻止本节点的祖先节点出现点击态 |
hover-start-time | number | 50 | 否 | 按住后多久出现点击态,单位毫秒 |
hover-stay-time | number | 400 | 否 | 手指松开后点击态保留时间,单位毫秒 |
4.1、示例代码
在开发者工具中预览效果
5、text 文本
1、文本标签
2、只能嵌套text标签
3、长按文字可以复制(只有该标签有此功能)
4、可以对 空格 回车 进行编码 ;
5、decode可以解析的有
<
>
&
'
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
selectable | boolean | false | 否 | 文本是否可选 |
space | string | 否 | 显示连续空格 | |
decode | boolean | false | 否 | 是否解码 |
space 的合法值
值 | 说明 |
---|---|
ensp | 中文字符空格一半大小 |
emsp | 中文字符空格大小 |
nbsp | 根据字体设置的空格大小 |
5.1、示例代码
在开发者工具中预览效果
6、image
图片。支持 JPG、PNG、SVG、WEBP、GIF 等格式,2.3.0 起支持云文件ID。
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
src | string | 否 | 图片资源地址 | |
mode | string | scaleToFill | 否 | 图片裁剪、缩放的模式 |
webp | boolean | false | 否 | 默认不解析 webP 格式,只支持网络资源 |
lazy-load | boolean | false | 否 | 图片懒加载,在即将进入一定范围(上下三屏)时才开始加载 |
show-menu-by-longpress | boolean | false | 否 | 开启长按图片显示识别小程序码菜单 |
binderror | eventhandle | 否 | 当错误发生时触发,event.detail = {errMsg} | |
bindload | eventhandle | 否 | 当图片载入完毕时触发,event.detail = {height, width} |
mode 的合法值
值 | 说明 |
---|---|
scaleToFill | 缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 |
aspectFit | 缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。 |
aspectFill | 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。 |
widthFix | 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变 |
heightFix | 缩放模式,高度不变,宽度自动变化,保持原图宽高比不变 |
top | 裁剪模式,不缩放图片,只显示图片的顶部区域 |
bottom | 裁剪模式,不缩放图片,只显示图片的底部区域 |
center | 裁剪模式,不缩放图片,只显示图片的中间区域 |
left | 裁剪模式,不缩放图片,只显示图片的左边区域 |
right | 裁剪模式,不缩放图片,只显示图片的右边区域 |
top left | 裁剪模式,不缩放图片,只显示图片的左上边区域 |
top right | 裁剪模式,不缩放图片,只显示图片的右上边区域 |
bottom left | 裁剪模式,不缩放图片,只显示图片的左下边区域 |
bottom right | 裁剪模式,不缩放图片,只显示图片的右下边区域 |
6.1、Bug & Tip
tip
:image组件默认宽度300px、高度240pxtip
:image组件中二维码/小程序码图片不支持长按识别。仅在wx.previewImage中支持长按识别
6.2、示例代码
在开发者工具中预览效果
7、swiper(轮播图)
1、存在默认样式:width:100% 、 height:150px swiper高度无法有内容撑开
2、swiper和图片的公式:
swiper width / swiper height= 原图的宽度 /原图的高度
width:swiper width * 原图的高度 / 原图的宽度
滑块视图容器。其中只可放置swiper-item组件,否则会导致未定义的行为。
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
indicator-dots | boolean | false | 否 | 是否显示面板指示点 | 1.0.0 |
indicator-color | color | rgba0, 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 |
display-multiple-items | number | 1 | 否 | 同时显示的滑块数量 | 1.9.0 |
skip-hidden-item-layout | boolean | false | 否 | 是否跳过未显示的滑块布局,设为 true 可优化复杂情况下的滑动性能,但会丢失隐藏状态滑块的布局信息 | 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 |
easing-function 的合法值
值 | 说明 | 最低版本 |
---|---|---|
default | 默认缓动函数 | |
linear | 线性动画 | |
easeInCubic | 缓入动画 | |
easeOutCubic | 缓出动画 | |
easeInOutCubic | 缓入缓出动画 |
7.1、change
事件 source
返回值
从 1.4.0 开始,change
事件增加 source
字段,表示导致变更的原因,可能值如下:
autoplay
自动播放导致swiper变化;touch
用户划动引起swiper变化;- 其它原因将用空字符串表示。
7.2、Bug & Tip
tip
: 如果在bindchange
的事件回调函数中使用setData
改变current
值,则有可能导致setData
被不停地调用,因而通常情况下请在改变current
值前检测source
字段来判断是否是由于用户触摸引起。
7.3、示例代码
在开发者工具中预览效果
8、navigator 导航组件类似超链接标签)
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
target | string | self | 否 | 在哪个目标上发生跳转,默认当前小程序 | 2.0.7 |
url | string | 否 | 当前小程序内的跳转链接 | 1.0.0 | |
open-type | string | navigate | 否 | 跳转方式 | 1.0.0 |
delta | number | 1 | 否 | 当 open-type 为 ‘navigateBack’ 时有效,表示回退的层数 | 1.0.0 |
app-id | string | 否 | 当target="miniProgram" 时有效,要打开的小程序 appId |
2.0.7 | |
path | string | 否 | 当target="miniProgram" 时有效,打开的页面路径,如果为空则打开首页 |
2.0.7 | |
extra-data | object | 否 | 当target="miniProgram" 时有效,需要传递给目标小程序的数据,目标小程序可在 App.onLaunch) ,App.onShow) 中获取到这份数据。详情 |
2.0.7 | |
version | string | release | 否 | 当target="miniProgram" 时有效,要打开的小程序版本 |
2.0.7 |
hover-class | string | navigator-hover | 否 | 指定点击时的样式类,当hover-class="none" 时,没有点击态效果 |
1.0.0 |
hover-stop-propagation | boolean | false | 否 | 指定是否阻止本节点的祖先节点出现点击态 | 1.5.0 |
hover-start-time | number | 50 | 否 | 按住后多久出现点击态,单位毫秒 | 1.0.0 |
hover-stay-time | number | 600 | 否 | 手指松开后点击态保留时间,单位毫秒 | 1.0.0 |
bindsuccess | string | 否 | 当target="miniProgram" 时有效,跳转小程序成功 |
2.0.7 | |
bindfail | string | 否 | 当target="miniProgram" 时有效,跳转小程序失败 |
2.0.7 | |
bindcomplete | string | 否 | 当target="miniProgram" 时有效,跳转小程序完成 |
2.0.7 |
target 的合法值
值 | 说明 | 最低版本 |
---|---|---|
self | 当前小程序 | |
miniProgram | 其它小程序 |
open-type 的合法值
值 | 说明 |
---|---|
navigate | 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。使用 wx.navigateBack 可以返回到原页面。小程序中页面栈最多十层。 |
redirect | 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。 |
switchTab | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 |
reLaunch | 关闭所有页面,打开到应用内的某个页面 |
navigateBack | 关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages 获取当前的页面栈,决定需要返回几层 |
exit | 退出小程序,target="miniProgram" 时生效 |
version 的合法值
值 | 说明 | 最低版本 |
---|---|---|
develop | 开发版 | |
trial | 体验版 | |
release | 正式版,仅在当前小程序为开发版或体验版时此参数有效;如果当前小程序是正式版,则打开的小程序必定是正式版。 |
8.1、使用限制
- 需要用户确认跳转 从
2.3.0
版本开始,在跳转至其他小程序前,将统一增加弹窗,询问是否跳转,用户确认后才可以跳转其他小程序。如果用户点击取消,则回调fail cancel
。 - 每个小程序可跳转的其他小程序数量限制为不超过 10 个 从 2.4.0 版本以及指定日期(具体待定)开始,开发者提交新版小程序代码时,如使用了跳转其他小程序功能,则需要在代码配置中声明将要跳转的小程序名单,限定不超过 10 个,否则将无法通过审核。该名单可在发布新版时更新,不支持动态修改。配置方法详见 配置。调用此接口时,所跳转的 appId 必须在配置列表中,否则回调
fail appId "${appId}" is not in navigateToMiniProgramAppIdList
。
8.2、关于调试
- 在开发者工具上调用此 API 并不会真实的跳转到另外的小程序,但是开发者工具会校验本次调用跳转是否成功。详情
- 开发者工具上支持被跳转的小程序处理接收参数的调试。详情
8.3、Bug & Tip
tip
:navigator-hover
默认为{background-color: rgba0, 0, 0, 0.1); opacity: 0.7;}
, navigator 的子节点背景色应为透明色
8.4、示例代码
在开发者工具中预览效果
9、rich-text(富文本标签)
1、标签字符串常用)
2、对象数组
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
nodes | array/string | [] | 否 | 节点列表/HTML String |
space | string | 否 | 显示连续空格 |
space 的合法值
值 | 说明 |
---|---|
ensp | 中文字符空格一半大小 |
emsp | 中文字符空格大小 |
nbsp | 根据字体设置的空格大小 |
9.1、nodes
现支持两种节点,通过type来区分,分别是元素节点和文本节点,默认是元素节点,在富文本区域里显示的HTML节点 元素节点:type = node
属性 | 说明 | 类型 | 必填 | 备注 |
---|---|---|---|---|
name | 标签名 | string | 是 | 支持部分受信任的 HTML 节点 |
attrs | 属性 | object | 否 | 支持部分受信任的属性,遵循 Pascal 命名法 |
children | 子节点列表 | array | 否 | 结构和 nodes 一致 |
文本节点:type = text
属性 | 说明 | 类型 | 必填 | 备注 |
---|---|---|---|---|
text | 文本 | string | 是 | 支持entities |
9.2、受信任的HTML节点及属性
全局支持class和style属性,不支持id属性。
节点 | 属性 |
---|---|
a | |
abbr | |
address | |
article | |
aside | |
b | |
bdi | |
bdo | dir |
big | |
blockquote | |
br | |
caption | |
center | |
cite | |
code | |
col | span,width |
colgroup | span,width |
dd | |
del | |
div | |
dl | |
dt | |
em | |
fieldset | |
font | |
footer | |
h1 | |
h2 | |
h3 | |
h4 | |
h5 | |
h6 | |
header | |
hr | |
i | |
img | alt,src,height,width |
ins | |
label | |
legend | |
li | |
mark | |
nav | |
ol | start,type |
p | |
pre | |
q | |
rt | |
ruby | |
s | |
section | |
small | |
span | |
strong | |
sub | |
sup | |
table | width |
tbody | |
td | colspan,height,rowspan,width |
tfoot | |
th | colspan,height,rowspan,width |
thead | |
tr | colspan,height,rowspan,width |
tt | |
u | |
ul |
9.4、Bug & Tip
tip
: nodes 不推荐使用 String 类型,性能会有所下降。tip
:rich-text
组件内屏蔽所有节点的事件。tip
: attrs 属性不支持 id ,支持 class 。tip
: name 属性大小写不敏感。tip
: 如果使用了不受信任的HTML节点,该节点及其所有子节点将会被移除。tip
: img 标签仅支持网络图片。tip
: 如果在自定义组件中使用rich-text
组件,那么仅自定义组件的 wxss 样式对rich-text
中的 class 生效。
9.5、示例代码
在开发者工具中预览效果
10、icon(图标)
图标。组件属性的长度单位默认为px,2.4.0起支持传入单位rpx/px)。
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
type | string | 是 | icon的类型,有效值:success, success_no_circle, info, warn, waiting, cancel, download, search, clear | |
size | number/string | 23 | 否 | icon的大小 |
color | string | 否 | icon的颜色,同css的color |
10.1、示例代码
在开发者工具中预览效果
11、radio-group
单项选择器,内部由多个 radio 组成。
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
bindchange | EventHandle | 否 | radio-group中选中项发生改变时触发 change 事件,detail = {value:[选中的radio的value的数组]} |
12、radio(单选)
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
value | string | 否 | radio 标识。当该radio 选中时,radio-group 的 change 事件会携带radio的value | 1.0.0 | |
checked | boolean | false | 否 | 当前是否选中 | 1.0.0 |
disabled | boolean | false | 否 | 是否禁用 | 1.0.0 |
color | string | #09BB07 | 否 | radio的颜色,同css的color | 1.0.0 |
12.1、示例代码
在开发者工具中预览效果
13、checkbox-group
多项选择器,内部由多个checkbox组成。
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
bindchange | EventHandle | 否 | checkbox-group中选中项发生改变时触发 change 事件,detail = {value:[选中的checkbox的value的数组]} |
14、checkbox(复选框)
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
value | string | 否 | checkbox标识,选中时触发checkbox-group的 change 事件,并携带 checkbox 的 value | 1.0.0 | |
disabled | boolean | false | 否 | 是否禁用 | 1.0.0 |
checked | boolean | false | 否 | 当前是否选中,可用来设置默认选中 | 1.0.0 |
color | string | #09BB07 | 否 | checkbox的颜色,同css的color | 1.0.0 |
示例代码
在开发者工具中预览效果
十 一、wxss语法
WXSS WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
WXSS 用来决定 WXML 的组件应该怎么显示。
为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。
与 CSS 相比,WXSS 扩展的特性有:
- 尺寸单位
- 样式导入
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 作为视觉稿的标准。
注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。
2、样式导入
使用@import
语句可以导入外联样式表,@import
后跟需要导入的外联样式表的相对路径,用;
表示语句结束。
示例代码:
/** common.wxss **/
.small-p {padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {padding:15px;
}
3、内联样式
框架组件上支持使用 style、class 属性来控制组件的样式。
- style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。
<view style="color:{{color}};" />
- class:用于指定样式规则,其属性值是样式规则中类选择器名样式类名)的集合,样式类名不需要带上
.
,样式类名之间用空格分隔。
<view class="normal_view" />
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 组件前边插入内容 |
5、全局样式与局部样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。
十二、自定义组件
从小程序基础库版本 1.6.3 开始,小程序支持简洁的组件化编程。所有自定义组件相关特性都需要基础库版本 1.6.3 或更高。
开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。
1、创建自定义组件
类似于页面,一个自定义组件由 json
wxml
wxss
js
4个文件组成。要编写一个自定义组件,首先需要在 json
文件中进行自定义组件声明(将 component
字段设为 true
可将这一组文件设为自定义组件):
{"component": true
}
同时,还要在 wxml
文件中编写组件模板,在 wxss
文件中加入组件样式,它们的写法与页面的写法类似。具体细节和注意事项参见 组件模板和样式 。
代码示例:
<!-- 这是自定义组件的内部WXML结构 -->
<view class="inner">{{innerText}}
</view>
<slot></slot>
/* 这里的样式只应用于这个自定义组件 */
.inner {color: red;
}
注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。
在自定义组件的 js
文件中,需要使用 Component)
来注册组件,并提供组件的属性定义、内部数据和自定义方法。
组件的属性值和内部数据将被用于组件 wxml
的渲染,其中,属性值是可由组件外部传入的。更多细节参见 Component构造器 。
代码示例:
1、页面.js文件中存放事件回调函数的时候存放在data同层级下
2、组件.js文件中存放事件回调函数的时候必须要存在在methods中
Component{properties: {// 这里定义了innerText属性,属性值可以在组件使用时指定innerText: {type: String,value: 'default value',}},data: {// 这里是一些组件内部数据someData: {}},methods: {// 这里是一个自定义方法customMethod: function){}}
})
2、使用自定义组件
使用已注册的自定义组件前,首先要在页面的 json
文件中进行引用声明。此时需要提供每个自定义组件的标签名和对应的自定义组件文件路径:
{"usingComponents": {"component-tag-name": "path/to/the/custom/component"}
}
这样,在页面的 wxml
中就可以像使用基础组件一样使用自定义组件。节点名即自定义组件的标签名,节点属性即传递给组件的属性值。
开发者工具 1.02.1810190 及以上版本支持在 app.json 中声明 usingComponents 字段,在此处声明的自定义组件视为全局自定义组件,在小程序内的页面或自定义组件中可以直接使用而无需再声明。
代码示例:
在开发者工具中预览效果
<view><!-- 以下是对一个自定义组件的引用 --><component-tag-name inner-text="Some text"></component-tag-name>
</view>
自定义组件的 wxml
节点结构在与数据结合之后,将被插入到引用位置内。
3、细节注意事项
一些需要注意的细节:
- 因为 WXML 节·点标签名只能是小写字母、中划线和下划线的组合,所以自定义组件的标签名也只能包含这些字符。
- 自定义组件也是可以引用自定义组件的,引用方法类似于页面引用自定义组件的方式(使用
usingComponents
字段)。 - 自定义组件和页面所在项目根目录名不能以“wx-”为前缀,否则会报错。
注意,是否在页面文件中使用 usingComponents
会使得页面的 this
对象的原型稍有差异,包括:
- 使用
usingComponents
页面的原型与不使用时不一致,即Object.getPrototypeOfthis)
结果不同。 - 使用
usingComponents
时会多一些方法,如selectComponent
。 - 出于性能考虑,使用
usingComponents
时,setData
内容不会被直接深复制,即this.setData{ field: obj })
后this.data.field === obj
。(深复制会在这个值被组件间传递时发生。)
如果页面比较复杂,新增或删除 usingComponents
定义段时建议重新测试一下。
4、组件间通信与事件(父子组件相互传递)
4.1、组件间通信
组件间的基本通信方式有以下几种。
- WXML 数据绑定:用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容数据(自基础库版本 2.0.9 开始,还可以在数据中包含函数)。具体在 组件模板和样式 章节中介绍。
- 事件:用于子组件向父组件传递数据,可以传递任意数据。
- 如果以上两种方式不足以满足需要,父组件还可以通过
this.selectComponent
方法获取子组件实例对象,这样就可以直接访问组件的任意数据和方法。
4.2、监听事件
事件系统是组件间通信的主要方式之一。自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件。关于事件的基本概念和用法,参见 事件 。
监听自定义组件事件的方法与监听基础组件事件的方法完全一致:
代码示例:
<!-- 当自定义组件触发“myevent”事件时,调用“onMyEvent”方法 -->
<component-tag-name bindmyevent="onMyEvent" />
<!-- 或者可以写成 -->
<component-tag-name bind:myevent="onMyEvent" />
Page{onMyEvent: functione){e.detail // 自定义组件触发事件时提供的detail对象}
})
4.3、触发事件
自定义组件触发事件时,需要使用 triggerEvent
方法,指定事件名、detail对象和事件选项:
代码示例:
在开发者工具中预览效果
<!-- 在自定义组件中 -->
<button bindtap="onTap">点击这个按钮将触发“myevent”事件</button>
Component{properties: {},methods: {onTap: function){var myEventDetail = {} // detail对象,提供给事件监听函数var myEventOption = {} // 触发事件的选项this.triggerEvent'myevent', myEventDetail, myEventOption)}}
})
触发事件的选项包括:
选项名 | 类型 | 是否必填 | 默认值 | 描述 |
---|---|---|---|---|
bubbles | Boolean | 否 | false | 事件是否冒泡 |
composed | Boolean | 否 | false | 事件是否可以穿越组件边界,为false时,事件将只能在引用组件的节点树上触发,不进入其他任何组件内部 |
capturePhase | Boolean | 否 | false | 事件是否拥有捕获阶段 |
关于冒泡和捕获阶段的概念,请阅读 事件 章节中的相关说明。
代码示例:
在开发者工具中预览效果
// 页面 page.wxml
<another-component bindcustomevent="pageEventListener1"><my-component bindcustomevent="pageEventListener2"></my-component>
</another-component>
// 组件 another-component.wxml
<view bindcustomevent="anotherEventListener"><slot />
</view>
// 组件 my-component.wxml
<view bindcustomevent="myEventListener"><slot />
</view>
// 组件 my-component.js
Component{methods: {onTap: function){this.triggerEvent'customevent', {}) // 只会触发 pageEventListener2this.triggerEvent'customevent', {}, { bubbles: true }) // 会依次触发 pageEventListener2 、 pageEventListener1this.triggerEvent'customevent', {}, { bubbles: true, composed: true }) // 会依次触发 pageEventListener2 、 anotherEventListener 、 pageEventListener1}}
})
4.4、获取组件实例
可在父组件里调用 this.selectComponent
,获取子组件的实例对象。(插件的自定义组件将返回 null
)
调用时需要传入一个匹配选择器 selector
,如:this.selectComponent".my-component")
。
selector
详细语法可查看 selector 语法参考文档。
代码示例:
在开发者工具中预览效果
// 父组件
Page{data: {},getChildComponent: function ) {const child = this.selectComponent'.my-component');console.logchild)}
})
在上例中,父组件将会获取 class
为 my-component
的子组件实例对象,即子组件的 this
。
若需要自定义 selectComponent
返回的数据,可使用内置 behavior
: wx://component-export
从基础库版本 2.2.3 开始提供支持。
使自定义组件中支持 export
定义段,这个定义段可以用于指定组件被 selectComponent
调用时的返回值。
代码示例:
在开发者工具中预览效果
// 自定义组件 my-component 内部
Component{behaviors: ['wx://component-export'],export) {return { myField: 'myValue' }}
})
<!-- 使用自定义组件时 -->
<my-component id="the-id" />
// 父组件调用
const child = this.selectComponent'#the-id') // 等于 { myField: 'myValue' }
在上例中,父组件获取 id
为 the-id
的子组件实例的时候,得到的是对象 { myField: 'myValue' }
。
5、Component 构造器
Component
构造器可用于定义组件,调用 Component
构造器时可以指定组件的属性、数据、方法等。
详细的参数含义和使用请参考 Component 参考文档。
Component{behaviors: [],properties: {myProperty: { // 属性名type: String,value: ''},myProperty2: String // 简化的定义方式},data: {}, // 私有数据,可用于模板渲染lifetimes: {// 生命周期函数,可以为函数,或一个在methods段中定义的方法名attached: function ) { },moved: function ) { },detached: function ) { },},// 生命周期函数,可以为函数,或一个在methods段中定义的方法名attached: function ) { }, // 此处attached的声明会被lifetimes字段中的声明覆盖ready: function) { },pageLifetimes: {// 组件所在页面的生命周期函数show: function ) { },hide: function ) { },resize: function ) { },},methods: {onMyButtonTap: function){this.setData{// 更新属性和数据的方法与更新页面数据的方法类似})},// 内部方法建议以下划线开头_myPrivateMethod: function){// 这里将 data.A[0].B 设为 'myPrivateData'this.setData{'A[0].B': 'myPrivateData'})},_propertyChange: functionnewVal, oldVal) {}}})
5.1、使用 Component 构造器构造页面
事实上,小程序的页面也可以视为自定义组件。因而,页面也可以使用 Component
构造器构造,拥有与普通组件一样的定义段与实例方法。但此时要求对应 json 文件中包含 usingComponents
定义段。
此时,组件的属性可以用于接收页面的参数,如访问页面 /pages/index/index?paramA=123¶mB=xyz
,如果声明有属性 paramA
或 paramB
,则它们会被赋值为 123
或 xyz
。
页面的生命周期方法(即 on
开头的方法),应写在 methods
定义段中。
代码示例:
{"usingComponents": {}
}
Component{properties: {paramA: Number,paramB: String,},methods: {onLoad: function) {this.data.paramA // 页面参数 paramA 的值this.data.paramB // 页面参数 paramB 的值}}})
使用 Component
构造器来构造页面的一个好处是可以使用 behaviors
来提取所有页面中公用的代码段。
例如,在所有页面被创建和销毁时都要执行同一段代码,就可以把这段代码提取到 behaviors
中。
代码示例:
// page-common-behavior.js
module.exports = Behavior{attached: function) {// 页面创建时执行console.info'Page loaded!')},detached: function) {// 页面销毁时执行console.info'Page unloaded!')}
})
// 页面 A
var pageCommonBehavior = require'./page-common-behavior')
Component{behaviors: [pageCommonBehavior],data: { /* ... */ },methods: { /* ... */ },
})
// 页面 B
var pageCommonBehavior = require'./page-common-behavior')
Component{behaviors: [pageCommonBehavior],data: { /* ... */ },methods: { /* ... */ },
})
6、小程序常用自定义属性
十三、小程序的生命周期
1、应用生命周期
属性 | 类型 | 必填 | 说明 | 一般使用场景 |
---|---|---|---|---|
onLaunch | function | 否 | 监听小程序初始化 | 应用第一次启动就触发的事件,获取用户个人信息 |
onshow | function | 否 | 监听小程序启动或切前台 | 对应用的数据或页面效果重置 |
onHIde | function | 否 | 监听小程序切后台 | 暂停或清除定时器 |
onError | function | 否 | 错误监听函数 | 在应用发生代码错误是,收集错误信息,用异步请求的方式发送到后台 |
onPageNotFound | function | 否 | 页面不存在监听函数 | 如果首页不存在,可以通过js在自定义跳转到第二个首页 |
2、页面生命周期
属性 | 类型 | 说明 |
---|---|---|
data | obiect | 页面的初始化数据 |
onLoad | function | 生命周期回调—监听页面加载 |
onShow | function | 生命周期回调一监听页面显示 |
onReady | function | 生命周期回调一监听页面初次渲染完成 |
onHide | function | 生命周期回调一监听页面隐藏 |
onUnload | function | 生命周期回调一监听页面卸载 |
onPullDownRefresh | function | 监听用户下拉动作 |
onReachBottom | function | 页面上拉触底事件的处理函数 |
onShareAppMessage | function | 用户点击右上角转发 |
onPageScroll | function | 页面滚动触发事件的处理函数 |
onResize | function | 页面尺寸改变时触发,详见响应显示区域变化 |
onTabltemTap | function | 当前是tab页时,点击tab时触发 |