视图层说明

最近更新时间:2024-03-28 15:39:01

我的收藏

概述

小程序框架的视图层由 WXML 和 WXSS 编写,由组件来进行展示。WXML 用于描述页面的结构,而 WXSS 用于描述页面的样式。WXS 是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
框架的逻辑层负责将数据转化为视图,同时将视图层的事件发送给逻辑层。这样,开发者可以专注于数据和逻辑的处理,而不必过多关注视图层的实现细节。
组件是视图的基本组成单元,可以帮助开发者更轻松地实现各种功能和交互效果。开发者可以自定义组件,也可以使用框架提供的组件库,从而快速地构建出具有原生 App 体验的服务。

WXML

WXML 相关操作,可参见 WXML 详情

WXSS

WXSS 相关操作,可参见 WXSS 详情

基础组件

说明

框架为开发者提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。
什么是组件:
组件是视图层的基本组成单元。
组件自带一些功能与 TMF 风格一致的样式。
一个组件通常包括开始标签结束标签属性用来修饰这个组件,内容在两个标签之内。
<tagname property="value">
Content goes here ...
</tagname>
说明:
所有组件与属性都是小写,以连字符-连接。

属性类型

类型
描述
注解
Boolean
布尔值
组件写上该属性,不管是什么值都被当作 True;只有组件上没有该属性时,属性值才为 False。如果属性值为变量,变量的值会被转换为 Boolean 类型
Number
数字
1, 2.5
String
字符串
"string"
Array
数组
[ 1, "string" ]
Object
对象
{ key: value }
EventHandler
事件处理函数名
"handlerName" 是 Page 中定义的事件处理函数名
Any
任意属性
-

公共属性

所有组件都有以下属性:
属性名
类型
描述
注解
id
string
组件的唯一标识
保持整个页面唯一
class
string
组件的唯一标识
在对应的 WXSS 中定义的样式类
style
string
组件的内联样式
可以动态设置的内联样式
hidden
boolean
组件是否显示
所有组件默认显示
date-*
any
自定义属性
组件上触发的事件时,会发送给事件处理函数
bind/catch
eventhandler
组件的事件
详见 WXML

特殊属性

几乎所有组件都有各自定义的属性,可以对该组件的功能或样式进行修饰,请参考各个 组件概览 的定义。

获取界面上的节点信息

WXML 节点信息

节点信息查询 API 可以用于获取节点属性、样式、在界面上的位置等信息。
最常见的用法是使用这个接口来查询某个节点的当前位置,以及界面的滚动位置。
示例代码:
const query = wx.createSelectorQuery()
query.select('#the-id').boundingClientRect(function (res) {
res.top // #the-id 节点的上边界坐标(相对于显示区域)
})
query.selectViewport().scrollOffset(function (res) {
res.scrollTop // 显示区域的竖直滚动位置
})
query.exec()
上述示例中, #the-id 是一个节点选择器,与 CSS 的选择器相近但略有区别,请参见 SelectorQuery 的相关说明。
在自定义组件或包含自定义组件的页面中,推荐使用 this.createSelectorQuery来代替 wx.createSelectorQuery,这样可以确保在正确的范围内选择节点。

WXML 节点布局相交状态

节点布局相交状态 API 可用于监听两个或多个组件节点在布局位置上的相交状态。这一组 API 常常可以用于,推断某些节点是否可以被用户看见、有多大比例可以被用户看见。
这一组 API 涉及的主要概念如下。
参照节点:监听的参照节点,取它的布局区域作为参照区域。如果有多个参照节点,则会取它们布局区域的交集作为参照区域。页面显示区域也可作为参照区域之一。
目标节点:监听的目标,默认只能是一个节点(使用 selectAll 选项时,可以同时监听多个节点)。
相交区域:目标节点的布局区域与参照区域的相交区域。
相交比例:相交区域占参照区域的比例。
阈值:相交比例如果达到阈值,则会触发监听器的回调函数。阈值可以有多个。
以下示例代码可以在目标节点(用选择器 .target-class 指定)每次进入或离开页面显示区域时,触发回调函数。
示例代码:
Page({
onLoad() {
wx.createIntersectionObserver().relativeToViewport().observe('.target-class', (res) => {
res.id // 目标节点 id
res.dataset // 目标节点 dataset
res.intersectionRatio // 相交区域占目标节点的布局区域的比例
res.intersectionRect // 相交区域
res.intersectionRect.left // 相交区域的左边界坐标
res.intersectionRect.top // 相交区域的上边界坐标
res.intersectionRect.width // 相交区域的宽度
res.intersectionRect.height // 相交区域的高度
})
}
})
以下示例代码可以在目标节点(用选择器 .target-class 指定)与参照节点(用选择器 .relative-class 指定)在页面显示区域内相交或相离,且相交或相离程度达到目标节点布局区域的20%和50%时,触发回调函数。
示例代码:
Page({
onLoad() {
wx.createIntersectionObserver(this, {
thresholds: [0.2, 0.5]
}).relativeTo('.relative-class').relativeToViewport().observe('.target-class', (res) => {
res.intersectionRatio // 相交区域占目标节点的布局区域的比例
res.intersectionRect // 相交区域
res.intersectionRect.left // 相交区域的左边界坐标
res.intersectionRect.top // 相交区域的上边界坐标
res.intersectionRect.width // 相交区域的宽度
res.intersectionRect.height // 相交区域的高度
})
}
})
说明:
与页面显示区域的相交区域并不准确代表用户可见的区域,因为参与计算的区域是“布局区域”,布局区域可能会在绘制时被其他节点裁剪隐藏(如遇祖先节点中 overflow 样式为 hidden 的节点)或遮盖(如遇 fixed 定位的节点)。
在自定义组件或包含自定义组件的页面中,推荐使用 this.createIntersectionObserver 来代替 wx.createIntersectionObserver,这样可以确保在正确的范围内选择节点。

响应显示区域变化

显示区域尺寸

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

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

小程序在手机上支持屏幕旋转。使小程序中的页面支持屏幕旋转的方法是:在 app.json 的 window 段中设置 "pageOrientation": "auto" ,或在页面 json 文件中配置 "pageOrientation": "auto"
以下是在单个页面 json 文件中启用屏幕旋转的示例。
代码示例:
{
"pageOrientation": "auto"
}

在iPad上启用屏幕选择支持

在 iPad 上运行的小程序可以支持屏幕旋转。使小程序支持 iPad 屏幕旋转的方法是:在 app.json 中添加 "resizable": true
代码示例:
{
"resizable": true
}

Media Query

有时,对于不同尺寸的显示区域,页面的布局会有所差异。此时可以使用 media query 来解决大多数问题。
代码示例:
.my-class {
width: 40px;
}

@media (min-width: 480px) {
/* 仅在 480px 或更宽的屏幕上生效的样式规则 */
.my-class {
width: 200px;
}
}

屏幕旋转事件

有时,仅仅使用 media query 无法控制一些精细的布局变化。此时可以使用 js 作为辅助。
在 js 中读取页面的显示区域尺寸,可以使用 selectorQuery.selectViewport 
页面尺寸发生改变的事件,可以使用页面的 onResize 来监听。对于自定义组件,可以使用 resize 生命周期来监听。回调函数中将返回显示区域的尺寸信息。
代码示例:
Page({
onResize(res) {
res.size.windowWidth // 新的显示区域宽度
res.size.windowHeight // 新的显示区域高度
}
})
Component({
pageLifetimes: {
resize(res) {
res.size.windowWidth // 新的显示区域宽度
res.size.windowHeight // 新的显示区域高度
}
}
})
此外,还可以使用wx.onWindowResize来监听(但这不是推荐的方式)。

动画

界面动画的常见方式

在小程序中,通常可以使用 CSS 渐变 和 CSS 动画 来创建简易的界面动画。
同时,还可以使用 wx.canvasContext 接口来动态创建简易的动画效果。
动画过程中,可以使用 bindtransitionend  bindanimationstart  bindanimationiteration   bindanimationend来监听动画事件。
transitionend:CSS 渐变结束或 wx.createAnimation 结束一个阶段。
animationstart:CSS 动画开始。
animationiteration:CSS 动画结束一个阶段。
animationend:CSS 动画结束。
说明:
这几个事件都不是冒泡事件,需要绑定在真正发生了动画的节点上才会生效。

高级的动画方式

在一些复杂场景下,上述的动画方法可能并不适用。
WXML 相应事件 的方式可以通过使用 QS 来响应事件的方法来动态调整节点的 style 属性。通过不断改变 style 属性的值可以做到动画效果。同时,这种方式也可以根据用户的触摸事件来动态地生成动画。
使用连续使用 setData 来改变界面的方法也可以达到动画的效果。这样可以任意地改变界面,但通常会产生较大的延迟或卡顿,甚至导致小程序僵死。此时可以通过将页面的 setData 改为 自定义模块组件 中的 setData 来提升性能。