小程序框架之视图层 View

摘要:
视图层View框架的视图层由WXML与WXSS编写,由组件来进行展示。将逻辑层的数据反应成视图,同时将视图层的事件发送给逻辑层。同时为了更适合开发微信小程序,WXSS对CSS进行了扩充以及修改。WXSWXS是小程序的一套脚本语言,结合WXML,可以构建出页面的结构。注意WXS不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。由于运行环境的差异,在iOS设备上小程序内的WXS会比JavaScript代码快2~20倍。

(1)视图层View

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

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

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

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

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

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

(2)WXML

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

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

用以下一些简单的例子来看看 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'}
  }
})

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

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

(3)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/屏幕宽度)
iPhone51rpx = 0.42px1px = 2.34rpx
iPhone61rpx = 0.5px1px = 2rpx
iPhone6 Plus1rpx = 0.552px1px = 1.81rpx

建议:开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。

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

样式导入

使用@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选择所有拥有 的组件
#id#firstname选择拥有 的组件
elementview选择所有 view 组件
element, elementview, checkbox选择所有文档的 view 组件和所有的 checkbox 组件
::afterview::after在 view 组件后边插入内容
::beforeview::before在 view 组件前边插入内容

全局样式与局部样式

定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。

(4)WXS

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

注意

  1. WXS 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。
  2. WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。
  3. WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API。
  4. WXS 函数不能作为组件的事件回调。
  5. 由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。

以下是一些使用 WXS 的简单示例,要完整了解 WXS 语法,请参考WXS 语法参考

页面渲染

<!--wxml-->
<wxs module="m1">
var msg = "hello world";

module.exports.message =msg;
</wxs>

<view> {{m1.message}} </view>

页面输出:

hello world

数据处理

//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]);
  }
  returnmax;
}

module.exports.getMax =getMax;
</wxs>

<!-- 调用 wxs 里面的 getMax 函数,参数为 page.js 里面的 array -->
<view> {{m1.getMax(array)}} </view>

页面输出:

5

wxs是专门用于wxml页面的,如果你有在页面中使用js脚本的需求可以使用,但是wxs是不能被其他js文件引用的。
目前我很少wxs,大多数工作都是在js中完成的。

(5)事件系统

什么是事件

  • 事件是视图层到逻辑层的通讯方式。
  • 事件可以将用户的行为反馈到逻辑层进行处理。
  • 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
  • 事件对象可以携带额外信息,如 id, dataset, touches。

事件的使用方式

  • 在组件中绑定一个事件处理函数。

bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。

<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
  • 在相应的Page定义中写上相应的事件处理函数,参数是event。
Page({
  tapName: function(event) {
    console.log(event)
  }
})
  • 可以看到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}]
}

使用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 tapName(event, ownerInstance) {
  console.log('tap wechat', JSON.stringify(event))
}
module.exports ={
  tapName: tapName
}

ownerInstance包含了一些方法,可以设置组件的样式和class,具体包含的方法以及为什么要用WXS函数响应事件,请点击查看详情

(6)事件详情

事件分类

事件分为冒泡事件和非冒泡事件:

  1. 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
  2. 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。

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

注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如formsubmit事件,inputinput事件,scroll-viewscroll事件,(详见各个组件)

事件绑定和冒泡

事件绑定的写法同组件的属性,以 key、value 的形式。

  • key 以bindcatch开头,然后跟上事件的类型,如bindtapcatchtouchstart。自基础库版本1.5.0起,在非原生组件中,bindcatch后可以紧跟一个冒号,其含义不变,如bind:tapcatch:touchstart
  • value 是一个字符串,需要在对应的 Page 中定义同名的函数。不然当触发事件的时候会报错。

bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。

如在下边这个例子中,点击 inner view 会先后调用handleTap3handleTap2(因为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>

案例1:

  <view id="outer" bindtap="handleTap1">outer view
    <view id="middle" catchtap="handleTap2">middle view
      <view id="inner" bindtap="handleTap3">inner view
      </view>
    </view>
  </view>
#outer{
   200px;
  height: 200px;
  background: red;
}
#middle{
   100px;
  height: 100px;
  background: yellow;
}
#inner{
   50px;
  height: 50px;
  background: green;
}


  handleTap1(){
    console.log('最外层')
  },
  handleTap2() {
    console.log('中层')
  },
  handleTap3() {
    console.log('内层')
  }

小程序框架之视图层 View第1张

事件的捕获阶段

事件捕获级别大于事件冒泡,详情见文章事件捕获与事件冒泡优先级

自基础库版本1.5.0起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用capture-bindcapture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。

在下面的代码中,点击 inner view 会先后调用handleTap2handleTap4handleTap3handleTap1

<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>

案例:

  <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>
#outer{
   200px;
  height: 200px;
  background: red;
}
#inner{
   100px;
  height: 100px;
  background: green;
}

  handleTap1(){
    console.log('bind:touchstart之handleTap1')
  },
  handleTap2() {
    console.log('capture-bind:touchstart之handleTap2')
  },
  handleTap3() {
    console.log('bind:touchstart之handleTap3')
  },
  handleTap4() {
    console.log('capture-bind:touchstart之handleTap4')
  }

小程序框架之视图层 View第2张

事件对象

如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。

BaseEvent 基础事件对象属性列表:

属性类型说明基础库版本
typeString事件类型
timeStampInteger事件生成时的时间戳
targetObject触发事件的组件的一些属性值集合
currentTargetObject当前组件的一些属性值集合
markObject事件标记数据2.7.1

案例:

<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me点我! </view>
tapName: function (event) {
    console.log(event)
  }

小程序框架之视图层 View第3张

type:事件类型
timeStamp:事件生成时的时间戳,页面打开到触发事件所经过的毫秒数
target:触发事件的组件的一些属性值集合,触发事件的源组件
    |
    |----id:事件源组件的id
    |----dataset:事件源组件上由data-开头的自定义属性组成的集合
currentTarget:当前组件的一些属性值集合
    |
    |----id:当前组件的id
    |----dataset:当前组件上由data-开头的自定义属性组成的集合
mark:事件标记数据
touches:触摸事件,当前停留在屏幕中的触摸点信息的数组
    |
    |-touches 是一个数组,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。

CustomEvent 自定义事件对象属性列表(继承 BaseEvent):

属性类型说明
detailObject额外的信息

TouchEvent 触摸事件对象属性列表(继承 BaseEvent):

属性类型说明
touchesArray触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouchesArray触摸事件,当前变化的触摸点信息的数组

特殊事件:canvas中的触摸事件不可冒泡,所以没有 currentTarget。

type

代表事件的类型。

timeStamp

页面打开到触发事件所经过的毫秒数。

target

触发事件的源组件。

属性类型说明
idString事件源组件的id
datasetObject事件源组件上由data-开头的自定义属性组成的集合

currentTarget

事件绑定的当前组件。

属性类型说明
idString当前组件的id
datasetObject当前组件上由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:function(event){
    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 中,如果按钮被点击,将触发bindViewTapbindButtonTap两个事件,事件携带的event.mark将包含myMarkanotherMark两项。

Page({
  bindViewTap: function(e) {
    e.mark.myMark === "last" //true
    e.mark.anotherMark === "leaf" //true
}
})

markdataset很相似,主要区别在于:mark会包含从触发事件的节点到根节点上所有的mark:属性值;而dataset仅包含一个节点的data-属性值。

细节注意事项:

  • 如果存在同名的mark,父节点的mark会被子节点覆盖。
  • 在自定义组件中接收事件时,mark不包含自定义组件外的节点的mark
  • 不同于dataset,节点的mark不会做连字符和大小写转换。

touches

touches 是一个数组,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。

Touch 对象

属性类型说明
identifierNumber触摸点的标识符
pageX, pageYNumber距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
clientX, clientYNumber距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴

CanvasTouch 对象

属性类型说明特殊说明
identifierNumber触摸点的标识符
x, yNumber距离 Canvas 左上角的距离,Canvas 的左上角为原点 ,横向为X轴,纵向为Y轴

changedTouches

changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。

detail

自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。

点击事件的detail带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。

(7)基础组件

框架为开发者提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。详细介绍请参考组件文档微信小程序~基础组件

什么是组件:

  • 组件是视图层的基本组成单元。
  • 组件自带一些功能与微信风格一致的样式。
  • 一个组件通常包括开始标签结束标签属性用来修饰这个组件,内容在两个标签之内。
<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任意属性

公共属性

所有组件都有以下属性:

属性名类型描述注解
idString组件的唯一标示保持整个页面唯一
classString组件的样式类在对应的 WXSS 中定义的样式类
styleString组件的内联样式可以动态设置的内联样式
hiddenBoolean组件是否显示所有组件默认显示
data-*Any自定义属性组件上触发的事件时,会发送给事件处理函数
bind* / catch*EventHandler组件的事件详见事件

特殊属性

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

(8)响应显示区域变化

显示区域尺寸

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

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

从小程序基础库版本2.4.0开始,小程序在手机上支持屏幕旋转。使小程序中的页面支持屏幕旋转的方法是:在app.jsonwindow段中设置"pageOrientation": "auto",或在页面 json 文件中配置"pageOrientation": "auto"

以下是在单个页面 json 文件中启用屏幕旋转的示例。

代码示例:

{
  "pageOrientation": "auto"}

如果页面添加了上述声明,则在屏幕旋转时,这个页面将随之旋转,显示区域尺寸也会随着屏幕旋转而变化。

从小程序基础库版本2.5.0开始,pageOrientation还可以被设置为landscape,表示固定为横屏显示。

在 iPad 上启用屏幕旋转支持

从小程序基础库版本2.3.0开始,在 iPad 上运行的小程序可以支持屏幕旋转。使小程序支持 iPad 屏幕旋转的方法是:在app.json中添加"resizable": true

代码示例:

{
  "resizable": true}

如果小程序添加了上述声明,则在屏幕旋转时,小程序将随之旋转,显示区域尺寸也会随着屏幕旋转而变化。注意:在 iPad 上不能单独配置某个页面是否支持屏幕旋转。

Media Query

有时,对于不同尺寸的显示区域,页面的布局会有所差异。此时可以使用 media query 来解决大多数问题。

代码示例:

.my-class{
   40px;
}

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

屏幕旋转事件

有时,仅仅使用 media query 无法控制一些精细的布局变化。此时可以使用 js 作为辅助。

在 js 中读取页面的显示区域尺寸,可以使用selectorQuery.selectViewport

页面尺寸发生改变的事件,可以使用页面的onResize来监听。对于自定义组件,可以使用 resize 生命周期来监听。回调函数中将返回显示区域的尺寸信息。(从基础库版本2.4.0开始支持。)

代码示例:

Page({
  onResize(res) {
    res.size.windowWidth //新的显示区域宽度
    res.size.windowHeight //新的显示区域高度
}
})
Component({
  pageLifetimes: {
    resize(res) {
      res.size.windowWidth //新的显示区域宽度
      res.size.windowHeight //新的显示区域高度
}
  }
})

此外,还可以使用wx.onWindowResize来监听(但这不是推荐的方式)。

Bug & tips:

  • Bug: Android 微信版本 6.7.3 中,live-pusher组件在屏幕旋转时方向异常。

(9)动画

界面动画的常见方式

在小程序中,通常可以使用CSS 渐变CSS 动画来创建简易的界面动画。

同时,还可以使用wx.createAnimation接口来动态创建简易的动画效果。

动画过程中,可以使用bindtransitionendbindanimationstartbindanimationiterationbindanimationend来监听动画事件。

事件名含义
transitionendCSS 渐变结束或wx.createAnimation结束一个阶段
animationstartCSS 动画开始
animationiterationCSS 动画结束一个阶段
animationendCSS 动画结束

注意:这几个事件都不是冒泡事件,需要绑定在真正发生了动画的节点上才会生效。

高级的动画方式

在一些复杂场景下,上述的动画方法可能并不适用。

WXS 响应事件的方式可以通过使用 WXS 来响应事件的方法来动态调整节点的 style 属性。通过不断改变 style 属性的值可以做到动画效果。同时,这种方式也可以根据用户的触摸事件来动态地生成动画。

使用连续使用 setData 来改变界面的方法也可以达到动画的效果。这样可以任意地改变界面,但通常会产生较大的延迟或卡顿,甚至导致小程序僵死。此时可以通过将页面的 setData 改为自定义组件中的 setData 来提升性能。下面的例子是使用 setData 来实现秒表动画的示例。

.

免责声明:文章转载自《小程序框架之视图层 View》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Python代码中执行curl命令查询couchbase数据Oracle11g温习-第十一章:管理undo下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

颠覆式前端UI开发框架:React

转自:http://www.infoq.com/cn/articles/subversion-front-end-ui-development-framework-react/ 基于HTML的前端界面开发正变得越来越复杂,其本质问题基本都可以归结于如何将来自于服务器端或者用户输入的动态数据高效的反映到复杂的用户界面上。而来自Facebook的React框...

使用android.view.TouchDelegate扩大View的触摸点击区域

Android4.0设计规定的有效可触摸的UI元素标准是48dp,转化为一个物理尺寸约为9毫米。7~10毫米,这是一个用户手指能准确并且舒适触摸的区域。 如下图所示,你的UI元素可能小于48dp,图标仅有32dp,按钮仅有40dp,但是他们的实际可操作焦点区域最好都应达到48dp的大小。 为使小的UI区域获得良好的触摸交互,根据View的特性,目前碰到了...

教育培训APP和小程序多端开发项目源码分享讲解

简介 本项目的一个教育培训服务APP。提供在线浏览机构信息、名师风采和课程预约订购等功能。 项目前端使用了avm.js多端开发技术,可同时编译为Android&iOSApp以及微信小程序; 后端使用APICloud数据云3.0云函数自定义接口。 技术要点 本项目在开发过程中,在“能拆就拆”的思想下,对项目进行细粒度的组件化拆解。 可以从中了解到组...

mpVue小程序全栈开发

1、微信小程序,mpVue和wepy的对比  2、  3、es6中关于数组的一些方法 1 <script> 2 let arr = [1,2,3,4] 3 // 遍历 4 arr.forEach(v => { 5 console.log(v) 6 })...

【腾讯Bugly干货分享】打造“微信小程序”组件化开发框架

本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/2nQzsuqq7Avgs8wsRizUhw 作者:Gcaufy 导语 Bugly 之前发了一篇关于微信小程序的开发经验分享(点击阅读),小伙伴们在公众账号后台问了很多关于小程序开发方面的问题,精神哥在查阅相关内容...

《QT Creator快速入门》第十一章(一):图形视图

一、图形视图框架结构 图形视图框架由场景QGraphicsScene、视图QGraphicsView、图形项QGraphicsItem组成,它提供了一套基于图形项模型视图编程方法。图形视图框架可以管理数量庞大的自定义2D图形项,比如要绘制上万个图形并对这些图形进行拖动、检测位置等操作的话使用图形视图框架就可以方便的管理它们。场景中可以包含各种形状的图形项,...