微信小程序 view 视图层//自学html
1.数据绑定canvas
数据绑定 WXML中的动态数据均来自对应Page的data。 简单绑定 数据绑定使用"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 } }) 关键字(须要在双引号以内) true:boolean 类型的 true,表明真值。 false: boolean 类型的 false,表明假值。 <checkbox checked="{{false}}"> </checkbox> 特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后表明真值。 运算 能够在{{}}内进行简单的运算,支持的有以下几种方式: 三元运算 <view hidden="{{flag ? true : false}}"> Hidden </view> 算数运算 <view> {{a + b}} + {{c}} + d </view> Page({ data: { a: 1, b: 2, c: 3 } }) view中的内容为3 + 3 + d 逻辑判断 <view wx:if="{{length > 5}}"> </view> 字符串运算 <view>{{"hello" + name}}</view> Page({ data:{ name:"MINA" } }) 数据路径运算 <view>{{object.key}} {{array[0]}}</view> Page({ data: { object: { key: 'Hello ' }, array: ['MINA'] } }) 组合 也能够在Mustache内直接进行组合,构成新的对象或者数组 数组 <view wx:for-items="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view> Page({ data: { zero: 0 } }) 最终组合成数组[0, 1, 2, 3, 4] 对象 <template is="objectCombine" data="{{for: a, bar: b}}"></template> Page({ data: { a: 1, b: 2 } }) 最终组合成的对象是{for: 1, bar: 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相同,也能够间接地表达 <template is="objectCombine" data="{{foo, bar}}"></template> Page({ data: { foo: 'my-foo', bar: 'my-bar' } }) 最终组合成的对象是{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}
2.条件渲染小程序
在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>
由于wx:if
是一个控制属性,须要将它添加到一个标签上。可是若是咱们想一次性判断多个组件标签,咱们可使用一个<block/>
标签将多个组件包装起来,并在上边使用wx:if
控制属性。微信
<block wx:if="{{true}}"> <view> view1 </view> <view> view2 </view> </block>
注意: <block/>
并非一个组件,它仅仅是一个包装元素,不会在页面中作任何渲染,只接受控制属性。框架
wx:if
vs hidden
由于wx:if
之中的模板也可能包含数据绑定,全部当wx:if
的条件值切换时,MINA有一个局部渲染的过程,由于它会确保条件块在切换时销毁或从新渲染。dom
同时wx:if
也是惰性的,若是在初始渲染条件为false
,MINA什么也不作,在条件第一次变成真的时候才开始局部渲染。ide
相比之下,hidden
就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。函数
通常来讲,wx:if
有更高的切换消耗而hidden
有更高的初始渲染消耗。所以,若是须要频繁切换的情景下,用hidden
更好,若是在运行时条件不大可能改变则wx:if
较好。
3.列表渲染,相似于TP的volist for循环
默认下:使用wx:for="{{变量名}}"嵌套到标签内,循环;
默认index为数组的key,item为value值;能够经过wx:for-index="i"更改成i,wx:for-item="vo"更改成vo值;
在组件上使用wx:for控制属性绑定一个数组,便可使用数组中各项的数据重复渲染该组件。 默认数组的当前项的下标变量名默认为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> wx:key 若是列表中项目的位置会动态改变或者有新的项目添加到列表中,而且但愿列表中的项目保持本身的特征和状态(如 <input/> 中的输入内容,<switch/> 的选中状态),须要使用 wx:key 来指定列表中项目的惟一的标识符。 wx:key 的值以两种形式提供 字符串,表明在 for 循环的 array 中 item 的某个 property,该 property 的值须要是列表中惟一的字符串或数字,且不能动态改变。 保留关键字 *this 表明在 for 循环中的 item 自己,这种表示须要 item 自己是一个惟一的字符串或者数字,如: 当数据改变触发渲染层从新渲染的时候,会校订带有 key 的组件,框架会确保他们被从新排序,而不是从新建立,以确保使组件保持自身的状态,而且提升列表渲染时的效率。 如不提供 wx:key,会报一个 warning, 若是明确知道该列表是静态,或者没必要关注其顺序,能够选择忽略。 示例代码: <switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch> <button bindtap="switch"> Switch </button> <button bindtap="addToFront"> Add to the front </button> <switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;"> {{item}} </switch> <button bindtap="addNumberToFront"> Add to the front </button> Page({ data: { objectArray: [ {id: 5, unique: 'unique_5'}, {id: 4, unique: 'unique_4'}, {id: 3, unique: 'unique_3'}, {id: 2, unique: 'unique_2'}, {id: 1, unique: 'unique_1'}, {id: 0, unique: 'unique_0'}, ], numberArray: [1, 2, 3, 4] }, switch: function(e) { const length = this.data.objectArray.length for (let i = 0; i < length; ++i) { const x = Math.floor(Math.random() * length) const y = Math.floor(Math.random() * length) const temp = this.data.objectArray[x] this.data.objectArray[x] = this.data.objectArray[y] this.data.objectArray[y] = temp } this.setData({ objectArray: this.data.objectArray }) }, addToFront: function(e) { const length = this.data.objectArray.length this.data.objectArray = [{id: length, unique: 'unique_' + length}].concat(this.data.objectArray) this.setData({ objectArray: this.data.objectArray }) }, addNumberToFront: function(e){ this.data.numberArray = [ this.data.numberArray.length + 1 ].concat(this.data.numberArray) this.setData({ numberArray: this.data.numberArray }) } })
4. 微信小程序 模板(template)
模板 WXML提供模板(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-15' } } }) 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>
4. 微信小程序 事件
1 事件的使用方式 2 3 在组件中绑定一个事件处理函数。 4 5 如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。 6 7 <view id="tapTest" data-hi="MINA" bindtap="tapName"> Click me! </view> 8 9 在相应的Page定义中写上相应的事件处理函数,参数是event。 10 11 Page({ 12 tapName: function(event) { 13 console.log(event) 14 } 15 }) 16 17 能够看到log出来的信息大体以下 18 19 { 20 "type": "tap", 21 "timeStamp": 1252, 22 "target": { 23 "id": "tapTest", 24 "offsetLeft": 0, 25 "offsetTop": 0, 26 "dataset": { 27 "hi": "MINA" 28 } 29 }, 30 "currentTarget": { 31 "id": "tapTest", 32 "offsetLeft": 0, 33 "offsetTop": 0, 34 "dataset": { 35 "hi": "MINA" 36 } 37 }, 38 "touches": [{ 39 "pageX": 30, 40 "pageY": 12, 41 "clientX": 30, 42 "clientY": 12, 43 "screenX": 112, 44 "screenY": 151 45 }], 46 "detail": { 47 "x": 30, 48 "y": 12 49 } 50 } 51 52 事件详解 53 事件分类 54 55 事件分为冒泡事件和非冒泡事件 56 57 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。 58 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。 59 60 WXML的冒泡事件列表: 61 类型 触发条件 62 touchstart 手指触摸 63 touchmove 手指触摸后移动 64 touchcancel 手指触摸动做被打断,如来电提醒,弹窗 65 touchend 手指触摸动做结束 66 tap 手指触摸后离开 67 longtap 手指触摸后,超过350ms再离开 68 69 注:除上表以外的其余组件自定义事件都是非冒泡事件,如<form/>的submit事件,<input/>的input事件,<scroll-view/>的scroll事件,(详见各个组件) 70 事件绑定 71 72 事件绑定的写法同组件的属性,以key、value的形式。 73 74 key以bind或catch开头,而后跟上事件的类型,如bindtap, catchtouchstart 75 value是一个字符串,须要在对应的Page中定义同名的函数。否则当触发事件的时候会报错。 76 77 bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定能够阻止冒泡事件向上冒泡。 78 79 如在下边这个例子中,点击inner view会前后触发handleTap1和handleTap2(由于tap事件会冒泡到middle view,而middle view阻止了tap事件冒泡,再也不向父节点传递),点击middle view会触发handleTap2,点击outter view会触发handleTap1。 80 81 <view id="outter" bindtap="handleTap1"> 82 outer view 83 <view id="middle" catchtap="handleTap2"> 84 middle view 85 <view id="inner" bindtap="handleTap3"> 86 inner view 87 </view> 88 </view> 89 </view> 90 91 事件对象 92 93 如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。 94 95 事件对象的属性列表: 96 属性 类型 说明 97 type String 事件类型 98 timeStamp Integer 事件生成时的时间戳 99 target Object 触发事件的组件的一些属性值集合 100 currentTarget Object 当前组件的一些属性值集合 101 touches Array 触摸事件,触摸点信息的数组 102 detail Object 额外的信息 103 CustomEvent 自定义事件对象属性列表(继承 BaseEvent): 104 属性 类型 说明 105 detail Object 额外的信息 106 107 TouchEvent 触摸事件对象属性列表(继承 BaseEvent): 108 属性 类型 说明 109 touches Array 触摸事件,当前停留在屏幕中的触摸点信息的数组 110 changedTouches Array 触摸事件,当前变化的触摸点信息的数组 111 112 特殊事件: <canvas/> 中的触摸事件不可冒泡,因此没有 currentTarget。 113 114 type 115 通用事件类型 116 timeStamp 117 118 该页面打开到触发事件所通过的毫秒数。 119 target 120 121 触发事件的源组件。 122 属性 说明 123 id 事件源组件的id 124 dataset 事件源组件上由data-开头的自定义属性组成的集合 125 offsetLeft, offsetTop 事件源组件的坐标系统中偏移量 126 currentTarget 127 128 事件绑定的当前组件。 129 属性 类型 说明 130 id String 当前组件的id 131 tagName String 当前组件的类型 132 dataset Object 当前组件上由data-开头的自定义属性组成的集合 133 134 说明: target 和 currentTarget 能够参考上例中,点击 inner view 时,handleTap3 收到的事件对象 target 和 currentTarget 都是 inner,而 handleTap2 收到的事件对象 target 就是 inner,currentTarget 就是 middle。 135 dataset 136 137 在组件中能够定义数据,这些数据将会经过事件传递给 SERVICE。 书写方式: 以data-开头,多个单词由连字符-连接,不能有大写(大写会自动转成小写)如data-element-type,最终在 event.target.dataset 中会将连字符转成驼峰elementType。 138 139 示例: 140 141 <view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view> 142 143 Page({ 144 bindViewTap:function(event){ 145 event.target.dataset.alphaBeta === 1 // - 会转为驼峰写法 146 event.target.dataset.alphabeta === 2 // 大写会转为小写 147 } 148 }) 149 150 touches 151 152 touches 是一个数组,每一个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。 153 Touch 对象 154 属性 类型 说明 155 identifier Number 触摸点的标识符 156 pageX, pageY Number 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴 157 clientX, clientY Number 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴 158 CanvasTouch 对象 159 属性 类型 说明 特殊说明 160 identifier Number 触摸点的标识符 161 x, y Number 距离 Canvas 左上角的距离,Canvas 的左上角为原点 ,横向为X轴,纵向为Y轴 162 changedTouches 163 164 changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。 165 detail 166 167 自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。
5. 微信小程序 引用
引用 两种方式:
1、import
2、inclode
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。 如:C import B,B import A,在C中可使用B定义的template,在B中可使用A定义的template,可是C不能使用A定义的template。 <!-- A.wxml --> <template name="A"> <text> A template </text> </template> <!-- B.wxml --> <import src="A.wxml"/> <template name="B"> <text> B template </text> </template> <!-- C.wxml --> <import src="B.wxml"/> <template is="A"/> <!-- Error! Can not use tempalte when not import A. --> <template is="B"/> include include能够将目标文件除了<template/>的整个代码引入,至关因而拷贝到include位置,如: <!-- index.wxml --> <include src="header.wxml"/> <view> body </view> <include src="footer.wxml"/> <!-- header.wxml --> <view> header </view> <!-- footer.wxml --> <view> footer </view>