微信小程序:MINA视图层

来源:互联网 发布:linux 日志切割脚本 编辑:程序博客网 时间:2024/05/21 22:51

一、WXML

WXML(WeiXin Markup Language)是MINA设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
WXML具备数据绑定、列表渲染、条件渲染、模板、事件、引用等能力,下面逐一进行详细介绍。

数据绑定
简单绑定

数据绑定使用“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  }})
运算

可以在{{}}内进行简单的运算,支持的有如下几种方式:
三元运算
<view hidden="{{flag ? true : false}}"> Hidden </view>
算数运算
<view> {{a + b}} + {{c}} + d </view>

Page({  data: {    a: 1,    b: 2,    c: 3  }})

逻辑判断
<view wx:if="{{length > 5}}"> </view>
字符串运算
<view>{{"hello" + name}}</view>

Page({  data:{    name:"MINA"  }})
组合

也可以在Mustache内直接进行组合,构成新的对象或者数组。
数组
<view wx:for-items="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>

Page({  data: {    zero: 0  }})

对象
<template is="objectCombine" data="{{for: a, bar: b}}"></template>

Page({  data: {    a: 1,    b: 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}

如果对象的 keyvalue相同,可以直接引用key

<template is="objectCombine" data="{{foo, bar}}"></template>

template是模板,is="objectCombine"是指拼接对象的模板,下文会有模板的详细介绍。

Page({  data: {     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}

条件渲染
wx:if

在MINA中,用wx:if="{{condition}}"来判断是否需要渲染该代码块:

<view wx:if="{{condition}}"> True </view>

也可以用wx:elifwx:else来添加一个else块:

<view wx:if="{{length > 5}}"> 1 </view><view wx:elif="{{length > 2}}"> 2 </view><view wx:else> 3 </view>

block wx:if
条件渲染多个组件标签时,使用<block/>进行包装,对block添加wx:if控制属性即可

<block wx:if="{{true}}">  <view> view1 </view>  <view> view2 </view></block>

注意:<block/>并不是组件,只是一个包装元素,不会在页面进行渲染,并且只接受控制属性。(ps:这么屌的元素应该多扩展一下)

wx:if vs hidden

因为wx:if之中的模板也可能包含数据绑定,所有当wx:if的条件值切换时,MINA有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时wx:if也是惰性的,如果在初始渲染条件为false,MINA什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if有更高的切换消耗而hidden有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用hidden更好,如果在运行时条件不大可能改变则wx:if较好。
(ps:频繁显隐用hidden,极少改变用wx:if。)

列表渲染
wx:for

在组件上使用wx:for控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的当前项的下标变量名默认为index,数组当前项的变量名默认为item。(下标:index,值:item)

<view wx:for="{{items}}">  {{index}}: {{item.message}}</view>

数据:

Page({  items: [{    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>
模板

模板(template)可以在模板中定义代码片段,然后在不同的地方调用。

定义模板

使用name属性作为模板名字,在<template/>内定义代码片段

<!--  index: int  msg: string  time: string--><template name="msgItem">  <view>    <text> {{index}}: {{msg}} </text>    <text> Time: {{time}} </text>  </view></template>
使用模板

使用is属性,声明需要的使用的模板,然后将模板所需要的data传入:

<template is="msgItem" data="{{...item}}"/>

Page({  data: {    item: {      index: 0,      msg: 'this is a template',      time: '2016-09-26'    }  }})

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>
模板的作用域

模板拥有自己的作用域,只能使用data传入的数据。

事件

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

事件的使用方式
  • 组件绑定事件处理函数

    <view id="tapTest" data-hi="MINA" bindtap="tapName"> Click me! </view>
  • 在相应的Page定义中写上相应的事件处理函数,参数是event

    Page({  tapName: function(event) {    console.log(event)  }})
  • log信息

    {"type": "tap","timeStamp": 1252,"target": {  "id": "tapTest",  "offsetLeft": 0,  "offsetTop": 0,  "dataset": {   "hi": "MINA"  }},"currentTarget": {  "id": "tapTest",  "offsetLeft": 0,  "offsetTop": 0,  "dataset": {    "hi": "MINA"  }},"touches": [{  "pageX": 30,  "pageY": 12,  "clientX": 30,  "clientY": 12,  "screenX": 112,  "screenY": 151}],"detail": {  "x": 30,  "y": 12}}
事件分类

事件分为冒泡事件非冒泡事件
冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。(子节点响应一次事件,父节点还会响应一次,直到根节点响应完成,所以有时候必须阻止事件冒泡)
非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
WXML的冒泡事件列表:

类型触发条件touchstart手指触摸touchmove手指触摸后移动touchcancel手指触摸动作被打断,如来电提醒,弹窗touchend手指触摸动作结束tap手指触摸后离开longtap手指触摸后,超过350ms再离开

注:除上表之外的其他组件自定义事件都是非冒泡事件,如<form/>的submit事件,<input/>的input事件,<scroll-view/>的scroll事件(后续会更新组件部分)。

事件绑定

绑定事件是以属性的方式,key、value:

  • key以bind或catch开头,然后跟上事件的类型,如bind tap,catchtouchstart
  • value是一个字符串,需要在对应的Page中定义同名的函数。不然当触发事件的时候会报错。

bind不会阻止冒泡事件向上冒泡,catch会阻止冒泡事件向上冒泡。

<view id="outter" bindtap="handleTap1">  outer view  <view id="middle" catchtap="handleTap2">    middle view    <view id="inner" bindtap="handleTap3">      inner view    </view>  </view></view>

上面例子中,点击 inner view会先后触发handleTap1handleTap2(因为tap事件会冒泡到middle view,而middle view阻止了tap事件冒泡,不再向父节点传递),点击middle view会触发handleTap2,点击ouster view会触发handleTap1

事件对象

当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象(特殊说明除外)。
事件对象属性列表:

属性类型说明typeString事件类型(如tap、longtap、touchstart等)timeStampInteger事件生成时的时间戳(页面打开到触发事件所经过的毫秒数)targetObject触发事件的组件的一些属性值集合currentTargetObject当前组件的一些属性值集合touchesArray触摸事件,触摸点信息的数组detailObject额外的信息,特殊事件所携带的数据,如单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息
target、currentTarget属性列表
属性说明id事件源组件的iddataset事件源组件上由data-开头的自定义属性组成的集合offsetLeft, offsetTop事件源组件的坐标系统中偏移量
dataset:

在组件中可以定义数据,这些数据将会通过事件传递给SERVICE。 书写方式: 以data-开头,多个单词由连字符-链接,不能有大写(大写会自动转成小写)如data-element-type,最终在event.target.dataset中会将连字符转成驼峰elementType

示例:

<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>

page:

Page({  bindViewTap:function(event){    event.target.dataset.alphaBeta == 1 // - 会转为驼峰写法    event.target.dataset.alphabeta == 2 // 大写会转为小写  }})
touches

touches是一个触摸点的数组,每个触摸点的属性如下:

属性说明pageX,pageY距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴clientX,clientY距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴screenX,screenY距离屏幕左上角的距离,屏幕左上角为原点,横向为X轴,纵向为Y轴
引用

WXML提供两种文件引用方式importinclude

import

import在该文件中使用目标文件定义的template,在item.wxml中定义了一个叫itemtemplate

<!-- item.wxml --><template name="item">  <text>{{text}}</text></template>

在index.wxml中引用了item.wxml,就可以使用item模板:

<import src="item.wxml"/><template is="item" data="{{text: 'forbar'}}"/>
import的作用域

import有作用域的概念,即只会import目标文件中定义的template,而不会import目标文件import的template。

include

include可以将目标文件除了<template/>的整个代码引入,相当于拷贝到include位置,如:

<!-- index.wxml --><include src="header.wxml"/><view> body </view><include src="footer.wxml"/>

header.wxml:

<!-- header.wxml --><view> header </view>

footer.wxml

<!-- footer.wxml --><view> footer </view>

二、WXSS

WXSS(WeiXin Style Sheets)是MINA设计的一套样式语言,用于描述WXML的组件样式。
WXSS用来决定WXML的组件应该怎么显示。
WXSS不仅具有CSS大部分特性,还同时为了更适合开发微信小程序,对CSS进行了扩充以及修改。
与css相比我们扩展的特性有:尺寸单位样式导入

尺寸单位

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在iPhone6上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

设备rpx换算px(屏幕宽度/750)px换算rpx(750/屏幕宽度)iPhone51rpx = 0.42px1px = 2.34pxiPhone61rpx = 0.5px1px = 2rpxiPhone6 Plus1rpx = 0.552px1px = 1.81rpx

注:rem(root em): 规定屏幕宽度为20rem;1rem = (750/20)rpm 。
建议:开发微信小程序时设计师可以用iPhone6作为视觉稿标准。

样式导入

外联样式

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

/** common.wxss **/.small-p{  padding:5px;}

引入:

/** app.wxss **/@import "common.wxss";.middle-p:{  padding:15px;}

内联样式

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

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

    <view style="color:{{color}};" />
  • class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上.,样式类名之间用空格分隔。

    <view class="normal_view" />

    选择器

选择器样例样例描述.class.intro选择所有拥有class="intro"的组件#id#firstname选择拥有id="firstname"的组件elementview选择所有view组件element, elementview checkbox选择所有文档的view组件和所有的checkbox组件::afterview::after在view组件后边插入内容::beforeview::before在view组件前边插入内容

全局样式与局部样式

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

三、组件

MINA提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。



0 0