天天看点

小程序视图层 View的开发

视图层 View

框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。

将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。

WXML(WeiXin Markup language) 用于描述页面的结构。

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

WXSS(WeiXin Style Sheet) 用于描述页面的样式。

组件(Component)是视图的基本组成单元。

WXML

WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。

要完整了解 WXML 语法,请参考WXML 语法参考。

用以下一些简单的例子来看看 WXML 具有什么能力:

数据绑定

{{message}}

// page.js

Page({

data: {

message: ‘Hello MINA!’

}

})

列表渲染

{{item}}

// page.js

Page({

data: {

array: [1, 2, 3, 4, 5]

}

})

条件渲染

WEBVIEW

APP

MINA

// page.js

Page({

data: {

view: ‘MINA’

}

})

模板

FirstName: {{firstName}}, LastName: {{lastName}}

// page.js

Page({

data: {

staffA: {firstName: ‘Hulk’, lastName: ‘Hu’},

staffB: {firstName: ‘Shang’, lastName: ‘You’},

staffC: {firstName: ‘Gideon’, lastName: ‘Lin’}

}

})

具体的能力以及使用方式在以下章节查看:

数据绑定、列表渲染、条件渲染、模板、引用

WXSS

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

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

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

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

尺寸单位

样式导入

尺寸单位

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 作为视觉稿的标准。

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

样式导入

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

示例代码:

@import “common.wxss”;

.middle-p {

padding:15px;

}

内联样式

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

style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。

class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上.,样式类名之间用空格分隔。

选择器

目前支持的选择器有:

选择器 样例 样例描述

.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响应事件

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

背景

有频繁用户交互的效果在小程序上表现是比较卡顿的,例如页面有 2 个元素 A 和 B,用户在 A 上做 touchmove 手势,要求 B 也跟随移动,movable-view 就是一个典型的例子。一次 touchmove 事件的响应过程为:

a、touchmove 事件从视图层(Webview)抛到逻辑层(App Service)

b、逻辑层(App Service)处理 touchmove 事件,再通过 setData 来改变 B 的位置

一次 touchmove 的响应需要经过 2 次的逻辑层和渲染层的通信以及一次渲染,通信的耗时比较大。此外 setData 渲染也会阻塞其它脚本执行,导致了整个用户交互的动画过程会有延迟。

实现方案

本方案基本的思路是减少通信的次数,让事件在视图层(Webview)响应。小程序的框架分为视图层(Webview)和逻辑层(App Service),这样分层的目的是管控,开发者的代码只能运行在逻辑层(App Service),而这个思路就必须要让开发者的代码运行在视图层(Webview),如下图所示的流程:

使用 WXS 函数用来响应小程序事件,目前只能响应内置组件的事件,不支持自定义组件事件。WXS 函数的除了纯逻辑的运算,还可以通过封装好的ComponentDescriptor 实例来访问以及设置组件的 class 和样式,对于交互动画,设置 style 和 class 足够了。WXS 函数的例子如下:

var wxsFunction = function(event, ownerInstance) {

var instance = ownerInstance.selectComponent(’.classSelector’) // 返回组件的实例

instance.setStyle({

“font-size”: “14px” // 支持rpx

})

instance.getDataset()

instance.setClass(className)

// …

return false // 不往上冒泡,相当于调用了同时调用了stopPropagation和preventDefault

}

其中入参 event 是小程序事件对象基础上多了 event.instance 来表示触发事件的组件的 ComponentDescriptor 实例。ownerInstance 表示的是触发事件的组件所在的组件的 ComponentDescriptor 实例,如果触发事件的组件是在页面内的,ownerInstance 表示的是页面实例。

ComponentDescriptor的定义如下:

方法 参数 描述 最低版本

selectComponent selector对象 返回组件的 ComponentDescriptor 实例。

selectAllComponents selector对象数组 返回组件的 ComponentDescriptor 实例数组。

setStyle Object/string 设置组件样式,支持rpx。设置的样式优先级比组件 wxml 里面定义的样式高。不能设置最顶层页面的样式。

addClass/removeClass/ hasClass string 设置组件的 class。设置的 class 优先级比组件 wxml 里面定义的 class 高。不能设置最顶层页面的 class。

getDataset 无 返回当前组件/页面的 dataset 对象

callMethod (funcName:string, args:object) 调用当前组件/页面在逻辑层(App Service)定义的函数。funcName表示函数名称,args表示函数的参数。

requestAnimationFrame Function 和原生 requestAnimationFrame 一样。用于设置动画。

getState 无 返回一个object对象,当有局部变量需要存储起来后续使用的时候用这个方法。

triggerEvent (eventName, detail) 和组件的triggerEvent一致。

getComputedStyle Array. 参数与 SelectorQuery 的 computedStyle 一致。 2.11.2

WXS 运行在视图层(Webview),里面的逻辑毕竟能做的事件比较少,需要有一个机制和逻辑层(App Service)开发者的代码通信,上面的 callMethod 是 WXS 里面调用逻辑层(App Service)开发者的代码的方法,而 WxsPropObserver 是逻辑层(App Service)开发者的代码调用 WXS 逻辑的机制。

使用方法

WXML定义事件:

上面的change:prop(属性前面带change:前缀)是在 prop 属性被设置的时候触发 WXS 函数,值必须用{{}}括起来。类似 Component 定义的 properties 里面的 observer 属性,在setData({propValue: newValue})调用之后会触发。

注意:WXS函数必须用{{}}括起来。当 prop 的值被设置 WXS 函数就会触发,而不只是值发生改变,所以在页面初始化的时候会调用一次WxsPropObserver的函数。

WXS文件test.wxs里面定义并导出事件处理函数和属性改变触发的函数:

module.exports = {

touchmove: function(event, instance) {

console.log(‘log event’, JSON.stringify(event))

},

propObserver: function(newValue, oldValue, ownerInstance, instance) {

console.log(‘prop observer’, newValue, oldValue)

}

}

更多示例请查看在微信小程序开发工具中预览效果

Tips

目前还不支持原生组件的事件、input和textarea组件的 bindinput 事件

1.02.1901170及以后版本的开发者工具上支持交互动画,最低版本基础库是2.4.4

目前在WXS函数里面仅支持console.log方式打日志定位问题,注意连续的重复日志会被过滤掉

继续阅读