微信小程序: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}
。
如果对象的 key
和value
相同,可以直接引用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:elif
和wx: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的冒泡事件列表:
注:除上表之外的其他组件自定义事件都是非冒泡事件,如<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
会先后触发handleTap1
和handleTap2
(因为tap事件会冒泡到middle view
,而middle view
阻止了tap事件冒泡,不再向父节点传递),点击middle view
会触发handleTap2
,点击ouster view
会触发handleTap1
。
事件对象
当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象(特殊说明除外)。
事件对象属性列表:
target、currentTarget属性列表
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是一个触摸点的数组,每个触摸点的属性如下:
引用
WXML提供两种文件引用方式import
和include
。
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'}}"/>
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物理像素。
注: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" />
选择器
全局样式与局部样式
定义在app.wxss中的样式为全局样式,作用于每一个页面。在page的wxss文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖app.wxss中相同的选择器。
三、组件
MINA提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。
- 微信小程序:MINA视图层
- 微信小程序:MINA逻辑层
- 微信小程序视图层详解(一)
- 微信小程序 -- 视图层的用法
- 微信小程序入门三:视图层
- 微信小程序开发--视图层1
- 微信小程序入门四:视图层事件
- 微信小程序开发--视图层2
- 小程序视图层wxml
- 微信小程序入门基础(2)—视图层
- 微信小程序基础-项目结构、app.json和视图层
- 【微信小程序开发•系列文章二】视图层
- 微信小程序学习笔记(5)--------框架之视图层
- 微信小程序的学习(3)-视图层WXML
- 微信小程序的学习(4)-视图层WXSS
- 微信小程序,学习笔记(一)框架,视图层
- 微信小程序,学习笔记(一)框架,视图层
- 微信小程序入门——视图层——视图、事件、模板
- 异步任务下载网络图片
- 236. Lowest Common Ancestor of a Binary Tree
- ViewPager详解(一)简单介绍
- AngularJS: $broadcast $emit $on
- [LeetCode-Java]35. Search Insert Position
- 微信小程序:MINA视图层
- Oracle 自定义结构(Record)
- dijkstra和spfa
- 我在中东肝PS
- noip2013花匠
- Mac上用Python安装PIL
- HTML块级元素&行内元素概览
- ViewPager详解(二)广告轮播图
- 关闭虚拟机vmware自动挂起