WXML语法概述:
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
微信官方教程如下:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/
特点:
- 布局的方式跟HTML是一模一样的。
- 标签的名字不再是传统的HTML的了,而是使用微信自己定义的一套,所以写代码的时候完全使用之前写HTML的方式去写,只不过改个标签名就可以了。
- WXML的语法,和一些模板语法比如Django中的模板语法非常的类似。
WXML数据绑定:
WXML 中的动态数据均来自对应 Page 的 data。 (wxml 可以使用 js 中 Page() 函数的 data 中的数据 )
我们的数据都是放在 js 中,从 Js中渲染到 wxml 中,就是通过数据绑定将 js 中的数据 渲染到 wxml 中。
例如:我们在 js中 如下定义数据:
那么使用的时候就可以直接在 wxml 中使用,不过使用的语法是 使用双括号的方法!!! 如下:
也可以在 把对象 渲染到 wxml 中,
例如:
使用的时候:
也可以在 把数组 渲染到 wxml 中,可以通过下标进行操作:
可以在 花括号 中进行一些简单的运算(判断 和 四则运算 ):
注意:在标签的属性中的时候 双括号外要加上 双引号!!!
所以,只有 放在双括号里面的才是作为数据来解析,
关于 变量渲染 的总结 :
- 使用双大花括号。
- 获取对象的值,通过下标获取数组中的值。
- 可以做运算,比如判断,四则运算等。
- 总而言之一句话:需要使用js中传过来的值,就必须使用双大花括号。
WXML条件渲染 :
当前标签 在满足一定的条件下才会被渲染,这就是条件渲染!
wx:if
在框架中,使用 wx:if=""
来判断是否需要渲染该代码块:
block wx:if
使用block 可以做到当满足一个条件的时候可以渲染多个标签,
因为 wx:if
是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/>
标签将多个组件包装起来,并在上边使用 wx:if
控制属性。
注意: <block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
还有需要注意的是:在 条件判断标签 中间 不能有其它不相关的标签,
例如如下就会报错:
WXML列表渲染(循环一个列表 ) :
wxml 中循环列表的基本方法:
通过语法wx:for="{{列表}}"来渲染一个列表
我们可以使用 item 变量 来遍历 列表中的数据,
我们可以使用 index 变量 来遍历 列表中的数据,
渲染之后的结果是:
默认的变量 是 item 和 index ,也可以自己定义:
循环中,默认的下标名称是index,默认的值的名称是item。如果想要修改循环列表的值和下标的名称,那么可以通过wx:for-index和wx:for-item来指定。示例代码如下:
此时就可以使用 value 变量 和 idx 变量了,
循环中渲染多个标签:
如果想要在循环中渲染多个标签,那么也可以通过block来实现。示例代码如下:
99乘法表例子 :
此时的数据就准备好了, 然后再通过 wxss 来将数据渲染 之后即可,
此时效果如下:
总结:
效果如下:
WXML列表渲染 之 wx:key :
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 <input/> 中的输入内容,<switch/> 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。
wx:key 的值以两种形式提供:
1,字符串或者数字,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。在写的时候,直接写这个 property 的名字就可以了,不需要写item.property的形式,并且不需要加中括号。
2,保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,*框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
及时列表中的组件没有发生状态改变,那么也建议使用wx:key。因为如果不使用,那么以后重新渲染的时候,就会把之前组件销毁掉,然后重新创建,性能会很低。
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
一句话,提供wx:key 就不会重新创建,不提供要重新创建,所以渲染列表时一定要提供wx:key
补充:js中的splice () 方法:
arrayObject.splice(index,howmany,item1,.....,itemX)
参数 | 描述 |
---|---|
index | 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。 |
howmany | 必需。要删除的项目数量。如果设置为 0,则不会删除项目。 |
item1, ..., itemX | 可选。向数组添加的新项目。 |
上述代码就是在索引0 处加入一个'a',
js 中 push() 向数组后面加一个, unshift() 向数组第一个加一个,
补充:
当数据发生改变,我们可以使用 this.setData()将数据设置回去,
wx: key 的使用:
此时假设 已经打开了swith1 ,
然后 点击 增加一个sitch 此时如下:(选中状态的 switch 变为了 switch5,此时就是有问题的)
wx:key 解决方法:
总而言之,wx:key 需要一个固定的唯一的值在这, 而且不需要 item. 也不需要写 双括号,直接写 属性名字即可!!!
用item 本身做为wx:key
有的时候,item 本身就是一个唯一的字符串或数字,可以直接做为wx:key ,此时可以使用item 本身,但是不可以直接使用,应该用 *this 代表!!!
例如:
此时 wx:key 是不行的,不能使用 item 来,应该使用*this 来代替,
这样就可以了,
其实,就算是我们的数据没有发生更新,我们也要 提供一个wx:key 来提高性能,
WXML模板技术 :
有些时候,一段布局代码我们需要在多个地方使用,那么我们可以将其定义成模板,然后把变量单独抽取出来,通过调用模板的时候再传递过去。示例代码如下:
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
调用模板:
<import src="../../templates/msgItem.wxml" />
<template is="msgItem" data="{{index:1,msg:"你好!我是知了课堂!",time:3000年10月22日}}"/>
创建模板:
现在的任务是 要 把 这两个 文件 .wxml 和 .wxss 做成模板,在其他地方直接使用,
把.wxml 中的标签放到 template 标签中,
把要做为 模板的wxss 文件直接放到 里面,
接下来,就可以直接 引用 刚刚弄好的模板了,
使用模板之 wxml 使用模板 :
在别的wxml 文件中使用模板时候,首先要 import 下,
import 之后,才可以使用模板,
使用模板:用is
注:定义模板的时候,用name ,使用模板用is
使用模板之 wxss 使用模板 :
wxss 在使用模板的时候,直接@import即可,
但是上面的模板都是固定的,都是死的,下面看动态模板
动态模板 创建:
动态模板的使用:
在使用动态模板的时候,使用 data进行传递数据,
这就是模板的好处,太棒了!!!
wxml 模板快捷传参:
代码如下:
效果如下:
对于上面的效果还可以 用如下更方便的方式实现:
...item 代表的就是 和之前的一样,就是 moto:item.moto,author:item.author
使用三个点的前提是:模板中使用的变量名字 刚好是 对象的key !!! (一般是模板结合 循环 )
WXML 之 include 标签 :
include
可以将目标文件除了 <template/>
<wxs/>
外的整个代码引入,相当于是拷贝到 include
位置
如果一段代码是不需要填入动态的数据,那么可以直接使用include
把这段代码引入到其他的地方。
就是相当于简单粗暴的 ctrl+ c 和 ctrl +v
但是,注意:如果所引用的文件中有 template 标签, 是不可以被引用的,即模板不可以被引用。
事件:
事件绑定:
在组件上使用bind:事件名称="执行的函数" 或者(bind事件名称=“执行的函数名”)
即可绑定事件。然后可以在js
文件中,实现具体的执行的函数
。以后在这个组件上发生了bind
后的事件,那么就会触发js
中的函数了。
参数传递:
参数传递,即将用户相应的 操作信息 传到 js中的处理函数中,进行处理,
此时 ,点击控制台输出如下:
可以看见 dataset 中是空的,
现在我们想 当用户点击 的时候,将 书的作者信息传递过来,
只需要在 data- 后面加上key ,然后,给出相应值即可,
此时,再点击时候,控制台输出的是:
可以看到 dataset 中就有了我们 想要传递的数据 author !!!
总之: data-我们想要传递过去的值 都可以这样传递,
又如:
点击之后 实现跳转功能:
可以通过 wx.navigateTo() ; 函数, 里面的参数是个对象,例如:
但是,注意 wx.navigateTo() 函数只能挑战到 非 tabBar 的页面,
如果想要实现跳转到 tabBar 的页面就得使用 switchTab()
注:这里的跳转是通过js 的函数 进行跳转的,微信小程序有它自己的组件实现跳转,可以直接在 wxml 中直接跳转,
携带数据 进行跳转:
此时在 跳转到的页面 的js 中的onLoad() 函数中可以接收到 我们传递的myData 数据,
注: onLoad() 函数是 一旦一个页面加载完毕,就会执行这个函数,
事件的冒泡 :
所谓 事件冒泡就是 当点击 黄色区域的时候, 可以冒泡到 蓝色区域,
即点击黄色的时候,也会触发cyan 的事件,
我们一般要阻止事件冒泡,
如果我们想要阻止事件的冒泡。我们可以以catch
开头来定义一个事件。这样就可以拦截事件的冒泡了。
即将 bind 换为 catch 即可!!!
事件分为冒泡事件和非冒泡事件:
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
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 |
注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的submit
事件,input 的input
事件,scroll-view 的scroll
事件,(详见各个组件)
绑定并阻止事件冒泡:
除 bind
外,也可以用 catch
来绑定事件。与 bind
不同, catch
会阻止事件向上冒泡。
事件对象:
如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象 我们可以打印出来看到。
它有如下属性列表:
属性 | 类型 | 说明 | 基础库版本 |
---|---|---|---|
type | String | 事件类型 | |
timeStamp | Integer | 事件生成时的时间戳 | |
target | Object | 触发事件的组件的一些属性值集合 | |
currentTarget | Object | 当前组件的一些属性值集合 | |
mark | Object | 事件标记数据 | 2.7.1 |
下面我们重点 区分下 target 和 currentTarget:
点击 黄色小的 时候:
只需要 记住如果事件的触发是通过事件冒泡 发生的,那么 target 就是指的是 事件源 的组件 ,而currentTarget 指的是当前的 组件 ,
一句话,target 是指源头, currentTarget 是指当前!!!