微信小程序,框架,视图层
学习链接:http://www.w3cschool.cn/weixinapp/
因为其实并非原创,但是并没有什么好的类别可选,所以修改成:“翻译”了。
熟悉
文档结构介绍
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
全局变量、对象、方法
普通类型
对象
-
App
应用程序全局实例,在
app.js
中定义,每个程序只有一个实例,可以通过如下方式获取var app = getApp();
该对象内容,全局属性或全局方法可以在这里面定义
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
使用方法:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
视图层(View)
数据绑定({{}}
)和条件渲染(wx:if
)
使用两个嵌套的大括号方式
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
-
普通绑定:
<view>{{name}}</view>
扫描二维码关注公众号,回复: 2290882 查看本文章 -
组件属性绑定: 必须使用引号引起来,在js改变
index
值的时候,页面会自动刷新最新值<view id="item-{{index}}"></view>
-
控制属性:即属性值是需要通过满足一定条件达到目的
<view wx:if="{{condition}}"></view>
也可以是条件表达式,或运算表达式:
<view hidden="{{flag ? true : false}}"></view>
多级条件判断,如:
if ... elif ... else
- 1
- 2
- 3
- 1
- 2
- 3
-
使用
<block>
块标签来使用条件判断控制多个组件的行为,<block>
只起到分组的作用,并不会真的渲染到出来- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
-
算术运算
- 1
- 2
- 1
- 2
-
对象绑定
其实和普通类型绑定差不多
- 1
- 1
PS: 使用条件来控制view
时候,和hidden
属性的比较
- view
的条件判断,会在条件中的值发生变化的时候,会先销毁原先的,然后满足条件的时候重新渲染和销毁
- hidden
属性控制view
的显示和隐藏,这个属性的组件始终会被渲染,只是在需要的时候控制它的隐藏和显示
最后比较得出:如果需要频繁频繁切换的情况下用hidden
属性控制,如果在绑定的数据基本不变的情况下使用wx:if
条件来控制
列表渲染(wx:for
)
-
wx:for
,可以同时生成多个元素参数属性说明:
wx:key="unique..."
:指定组件的唯一标识,列表发生变化需要保持自身的状态和特征不发生变化,并且能在重新渲染的时候,重新排序;wx:key="*this"
:功能同上,但这个是要求项目中的item本身是唯一的,也就是你需要用到的属性值是唯一;wx:for-index="index"
:指定循环的下标变量名,默认:index
;wx:for-item="item"
: 指定当前项变量名,默认:item
例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
模版(template)
用来定义代码片段,完成之后可以在其他地方通过模版直接套用该模版中组件。
-
模版定义:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
-
模版使用:通过模版名称
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
-
模版和列表
wx:for
结合使用,同时生成多个模版使用的时候使用半闭合标签,以及需要使用到
is=""
来指定模版名称去使用的指定模版- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
-
运行时通过条件判断来决定使用哪个模版
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
PS: 生成的模版拥有自己独立的作用域,因此所使用的数据必须是data=
中指定的数据
事件处理
-
点击事件:
bindtap
例如:
<button class="button button-refresh" bindtap="refreshDateTbl">refresh</button>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
从输出结果得出,event 对象主要包含以下部分
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
-
事件对象:
event
原生事件属性列表:
type
: 即当前事件类型(tap / touch);currentTarget
:表示当前组件信息集合;target
: 通过打印看了下,console.log( event.currentTarget == event.target );
结果:false
,说明currentTarget
和target
不是同一个对象,但是里面的东西应该都是当前目标的属性(不是很确定);看文档解释是:触发事件的组件的属性集合(currentTarget是当前,target是触发事件的组件,不是很明白区别在哪??)timeStamp
: 这个时间也不知道是啥,应该不是点击动作时间也不是响应时间,有2.8秒之久。(理解错误,正确:事件生成的时间戳)
自定义事件对象属性列表:
detail
: 当前组件的坐标(x, y);
触摸事件对象属性列表:
touches
:这个接触的对象数组,难道是和事件冒泡有关?表示网上冒泡的父对象集合??瞎猜,应该是:当前触摸事件的触摸点信息数组;changedTouches
: 应该和上面的touches
有联系,解释为:当前变化的触摸点信息的数组;
以下是各事件属性的内容,很容易理解
target
:id
,dataset
,offsetLeft
,offsetTop
,dataset
要解释下:表示事件源组件上的自定义属性data-
的集合;-
currentTarget
:id
, ‘dataset,
tagName`;dataset
:自定义属性集合,其中自定义属性data-
中必须都为小写,需要使用-
作为连接符, 自定义后的属性都会出现在事件对象的dataset
对象上,举例:<view data-my-name="lizc" data-myAge="30"></view>
最终
name
和age
可以通过如下方式去调用- 1
- 2
- 1
- 2
因此推荐使用
-
连接符去书写自定义数据属性 -
touches
:触摸点数组,触摸点对象Touch
或CanvasTouch
的集合,表示当前页面上所有触摸点的集合,包含属性:Touch
对象identifier
: 触摸点标识符,类型:Number,应该是个类似标记的东西,或者索引之类的,唯一;pageX
,pageY
:相对于整个文档而言,距离文档左上角的x
和y
轴的距离;clientX
,clientY
:相对于可是区域而言,xy
轴的距离
CanvasTouch
对象:identifier
: 同上;x
,y
:这个只有一个坐标,即相对画布左上角而言的坐标;
-
changedTouches
:表示发生变化的触摸点对象集合,比如该触摸点发生了touchstart
,touchmove
,touchend
,touchcancel
变化; -
detail
:跟自定义事件有关,自定义事件携带的数据,不是很明白,具体内容有待考证。
PS1: 中午休息了会,打开代码,随便点击了几下按钮,突然发现这个timestamp
可能是什么鬼了!!!
下面是打印
```
Object {type: "tap", timeStamp: 5053127, target: Object, currentTarget: Object, detail: Object…}
Object {type: "tap", timeStamp: 5053311, target: Object, currentTarget: Object, detail: Object…}
Object {type: "tap", timeStamp: 5053496, target: Object, currentTarget: Object, detail: Object…}
Object {type: "tap", timeStamp: 5054722, target: Object, currentTarget: Object, detail: Object…}
Object {type: "tap", timeStamp: 5054936, target: Object, currentTarget: Object, detail: Object…}
Object {type: "tap", timeStamp: 5055120, target: Object, currentTarget: Object, detail: Object…}
new Date() 一下:
new Date(0)
Thu Jan 01 1970 08:00:00 GMT+0800 (中国标准时间)
new Date(5053127)
Thu Jan 01 1970 09:24:13 GMT+0800 (中国标准时间)
结果发现相差了 1:24:13,这不是刚刚启动程序那会!!!!
```
从而得出结论:这个timestamp
应该就是程序运行的时间,单位:(ms)
PS2: 好傻!!看完事件大概,居然没继续往下看,文档下面就有每个属性的明确解释
timeStamp: 事件生成时的时间戳;我还把它当成了程序运行时间~~~~, 也就是该页面打开到事件触发时的这段时间。
-
事件类型:冒泡和非冒泡
冒泡事件:(除以下冒泡事件之外的其他事件均为非冒泡事件)
- touchstart: 手指刚碰触到屏幕的时候触发的事件;
- touchmove:手指触摸后移动时触发;
- touchcancel:手指触摸动作被打断,即非正常退出触摸,如来电或短信等;
- touchend:手指触摸结束;
- tap:手指触摸,即点击事件,触摸即离开;
- longtap:手指触摸后超过350ms再离开,会被判定为长按。
非冒泡事件
<form/>
标签的submit
事件<input/>
标签的input
事件<scroll-view/>
标签的scroll
事件
特殊事件:
<canvas />
的触摸事件不可冒泡,因此没有currentTarget
,理解:因为不存在冒泡行为,也就是说被点击事件和当前事件组件永远只可能是同一个组件。
-
target
和currentTarget
对比分析测试代码:日期列表,点击日期行,通过事件冒泡去触发父组件的
tapDateRow
事件- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
从输出可知,target即你点击的那个组件,也就是触发点击事件的组件,而
currentTarget
是你绑定点击事件的那个组件,如果点击事件句柄同时绑定在被点击的那个组件上,那么这两个对象是不是应该是指同一个组件呢?(猜测对一半错一半,验证如下:)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
结论:通过输出可知,两个对象的内容是一模一样的,说明这两个属性都是代表着当前被点击的组件,但是两者却不是指向同一个空间,即该组件。说明这两个对象具有自己独立的内存空间,而非在绑定事件和触发事件对象相同时都指向同一个内存空间。
-
事件绑定:
bind
和catch
,即冒泡和非冒泡bind:
- 1
- 2
- 1
- 2
catch:
- 1
- 2
- 1
- 2
例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 点击 view3 会调用 f1, 然后调用 f2,到此结束,因为 view2 用的是非冒泡绑定,阻止了事件继续往上冒泡到 view1;
- 点击 view2 只会调到 f2;
- 点击 view1 只会调到 f1;
事件总结:
- 事件对象:
event
; - 事件类型:冒泡和非冒泡;
- 事件绑定:
bindtap
,bindtouch*
; - 事件源和触发源:
event.currentTarget
和event.target
;
a.id
:事件组件对象的id
;
b.target
:自定义属性集合dataset
(属性定义:data-my-name
,使用:event.target.dataset.myName
);
c.offsetLeft/offsetTop
: 事件组件的left/top
实际值。 - 事件戳:
event.timeStamp
,单位:(ms); - 触摸点对象:
event.touches
(Touch
:identifier
,pageX/pageY
,clientX/clientY
;CanvasTouch
:identifier
,x/y
); - 变化的触摸点对象:
event.changedTouches
; - 自定义事件携带的数据对象:
event.detail
。
引用
引用外部文件方式:import
和 include
,两个引入刚好相反或者说互补,前者是引入文件中的模版代码template
,而后者是引入文件中除了template
定义的之外的所有代码完整拷贝到当前位置。
-
import
使用
import
引入时不能嵌套引入,即:加入a.wxml
中引入了b.wxml
中的模版,然后b.wxml
引入了c.wxml
中的模版,那么a.wxml
中也无法直接引入c.wxml
中的模版。- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
未报错,只是警告,但也可知
import
无法嵌套跨文件引入:- 1
- 2
- 1
- 2
-
include
这个引入的是除了
template
定义之外的所有代码,相当于将代码拷贝到当前位置。- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
结果: 如下,只是单纯引入了除
template
之外的代码,并且是拷贝到inlucde
使用的当前位置