微信小程序开发03(WXML语法)

小程序WXML语法

1.1、事件系统

什么是事件

  • 事件是视图层到逻辑层的通讯方式
  • 事件可以将用户的行为反馈到逻辑层进行处理
  • 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数
  • 事件对象可以携带额外信息,如 id, dataset,
    touches
    事件的使用方式
    在组件中绑定一个事件处理函数
javascript 复制代码
<button type="primary" bindtap="tapName"> Click me! </button>
<view bindtap="tapName"> Click me! </view>
javascript 复制代码
// pages/event/event.js
Page({
  tapName(){
    console.log("点击");
   }
})

Event对象

在小程序中,也具有事件对象event

javascript 复制代码
Page({
  tapName(e){
    console.log(e);
   }
})
属性 类型 说明
type String 事件类型
timeStamp Integer 事件生成时的时间戳
target Object 触发事件的组件的一些属性值集合
currentTarget Object 当前组件的一些属性值集合
mark Object 事件标记数据
detail Object 额外的信息
touches Array 触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouches Array 触摸事件,当前变化的触摸点信息的数组

1.2、事件分类

事件分为冒泡事件和非冒泡事件:

  • 冒泡事件(bind):当一个组件上的事件被触发后,该事件会向父节点传递
  • 非冒泡事件(catch):当一个组件上的事件被触发后,该事件不会向父节点传递

冒泡事件(bind)

当一个组件上的事件被触发后,该事件会向父节点传递

javascript 复制代码
<view bindtap="bindParentHandle">
  <button type="primary" bindtap="bindChildHandle">冒泡事件</button>
</view>
javascript 复制代码
// pages/event/event.js
Page({
  bindParentHandle(){
    console.log("父级事件");
   },
  bindChildHandle(){
    console.log("子级事件");
   }
})

非冒泡事件(catch)

当一个组件上的事件被触发后,该事件不会向父节点传递

javascript 复制代码
<view catchtap="catchParentHandle">
  <button type="primary" catchtap="catchChildHandle">非冒泡事件</button>
</view>
javascript 复制代码
// pages/event/event.js
Page({
  catchParentHandle(){
    console.log("非冒泡父级事件");
   },
  catchChildHandle(){
    console.log("非冒泡子级事件");
   }
})

1.3、事件类型

在微信小程序中,事件有很多中类型,通过bind和catch与下面的类型组合产生不同类型的事件
事件类型列表

类型 触发条件
touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
touchend 手指触摸动作结束
tap 手指触摸后马上离开
longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发
longtap 手指触摸后,超过350ms再离开(推荐使用 longpress 事件代替)
javascript 复制代码
<button type="primary" bindtouchstart="bindtouchStartHandle">touchstart bind</button>
<button type="primary" catchtouchstart="catchtouchStartHandle">touchstart catch</button>
<button type="primary" bindlongpress="bindlongpressHandle">longpress bind</button>
<button type="primary" catchlongpress="catchlongpressHandle">longpress catch</button>
javascript 复制代码
// pages/event/event.js
Page({
  bindtouchStartHandle(){
    console.log("bind与touchStart组合");
   },
  catchtouchStartHandle(){
    console.log("catch与touchStart组合");
   },
  bindlongpressHandle(){
    console.log("bind与longpress组合");
   },
  catchlongpressHandle(){
    console.log("catch与longpress组合");
   }
})

1.4、事件携带参数

事件在触发的过程中,我们可以携带参数

主要有两种方式:

  • event对象中的currentTarget读取携带参数
  • event对象中的mark读取携带参数
    currentTarget 携带参数
    在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。
javascript 复制代码
<view data-id="1001" bindtap="bindViewTap"> 携带参数 </view>
javascript 复制代码
// pages/event/event.js
Page({
  bindViewTap(e){
    console.log(e.currentTarget.dataset.id);
   }
})

温馨提示

在wxml中添加数据的时候,必须在自定义属性前添加data-*

mark 携带参数

可以使用 mark 来识别具体触发事件的 target 节点。此外, mark 还可以用于承载一些自定义数据(类似于 dataset )。

当事件触发时,事件冒泡路径上所有的 mark 会被合并,并返回给事件回调函数。(即使事件不是冒泡事件,也会 mark 。)

javascript 复制代码
<view mark:parentMark="父级" bindtap="bindMarkTap">
    <button type="primary" mark:childMark="子级" bindtap="bindButtonTap">按钮</button>
</view>
javascript 复制代码
// pages/event/event.js
Page({
  bindMarkTap(e){
    console.log(e.mark);
   },
  bindButtonTap(e){
    console.log(e.mark);
   }
})

1.5、条件渲染

小程序提供了在wxml模板中,使用条件渲染

  1. wx:if
  2. wx:else
  3. wx:elif
  4. hidden

wx:if

在小程序中,使用 wx:if="" 来判断是否需要渲染该代码块

javascript 复制代码
<view wx:if="{{ flag }}">我是孙悟空</view>
javascript 复制代码
Page({
  data: {
    flag:true
   }
})

wx:else

有wx:if匹配的同时还有wx:else

javascript 复制代码
<view wx:if="{{ flag }}">我是孙悟空</view>
<view wx:else="{{ flag }}">我是六耳猕猴</view>
javascript 复制代码
Page({
  data: {
    flag:false
   }
})

wx:elif

如同在javascript中,单纯的if...else是不够用的,所以引入了elif

javascript 复制代码
<view wx:if="{{length === 1}}"> 1 </view>
<view wx:elif="{{length === 2}}"> 2 </view>
<view wx:else>未知</view>
javascript 复制代码
Page({
  data: {
    length:1
   }
})

hidden

hidden 与wx:if类似,同样可以来判断是否需要渲染该代码块

javascript 复制代码
<view hidden="{{ hidden }}">果子熟了</view>
javascript 复制代码
Page({
  data: {
    hidden:false
   }
})

wx:if vs hidden 区别

  • 因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。

  • 同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。

  • 相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的基于CSS控制显示与隐藏。

  • 一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好

1.6、列表渲染

在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件

基本使用

默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item

javascript 复制代码
<view>
  <view wx:for="{{ users }}">{{ item }}</view>
</view>
javascript 复制代码
Page({
  data: {
    users:["itbaizhan","sxt"]
   }
})

使用 wx:for-item 可以指定数组当前元素的变量名

使用 wx:for-index 可以指定数组当前下标的变量名

javascript 复制代码
<view>
  <view 
    wx:for="{{ users }}" 
    wx:for-item="user"
    wx:for-index="ids"
    >
     {{ user }}-{{ ids }}
  </view>
</view>
javascript 复制代码
Page({
  data: {
    users:["itbaizhan","sxt"]
   }
})

复杂数据

网络请求拿到的数据是json格式,相对比要复杂一些

javascript 复制代码
<view>
  <block wx:for="{{ result }}" wx:for-item="item">
    <view>{{ item.name }}</view>
    <image src="{{ item.pic }}"></image>
    <view>{{ item.description }}</view>
    <view>{{ item.price }}</view>
    <view>{{ item.city }}</view>
  </block>
</view>
javascript 复制代码
Page({
  data: {
    result: [{
        "id": 1,
        "name": "美食-甜豆干",
        "pic": "http://iwenwiki.com:3002/images/goods/1.jpg",
        "description": "津津卤汁豆腐干苏州特产豆干零食素食老字号食品豆制品小吃90g*10",
        "price": "39.90",
        "type": 0,
        "buynum": "435",
        "city": "北京"
       },
       {
        "id": 2,
        "name": "好欢螺螺蛳粉300g*6袋",
        "pic": "http://iwenwiki.com:3002/images/goods/2.jpg",
        "description": "好欢螺螺蛳粉300g*6袋柳州特产螺狮粉美食螺丝粉煮水方便面酸辣粉",
        "price": "69.99",
        "type": 0,
        "buynum": "3333",
        "city": "北京"
       }
     ]
   }
})

1.7、列表渲染_key属性

wx:key

如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态,需要使用 wx:key 来指定列表中项目的唯一的标识符

当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率

温馨提示

如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略

javascript 复制代码
<view wx:for="{{ news }}" wx:for-item="item" wx:key="id">
  <view>{{ item.name }}</view>
</view>
javascript 复制代码
Page({
  data: {
    news:[
       {
        "id": 1,
        "name": "美食-甜豆干"
       },
       {
        "id": 2,
        "name": "好欢螺螺蛳粉300g*6袋"
       }
     ]
   }
})

当我们想数组中添加新的数据,并且放在首位的时候,在渲染的时候,key就起到了作用

javascript 复制代码
<button type="primary" bindtap="clickHandle">增加数据</button>
<view wx:for="{{ news }}" wx:for-item="item" wx:key="id">
  <view>{{ item.name }}</view>
</view>
javascript 复制代码
Page({
  data: {
    news:[
       {
        "id": 1,
        "name": "美食-甜豆干"
       },
       {
        "id": 2,
        "name": "好欢螺螺蛳粉300g*6袋"
       }
     ]
   },
  clickHandle(){
    this.setData({
      news:this.data.news.concat({
        "id":"3",
        "name": "对夹"
       })
     })
   }
})

1.8、列表渲染_应用

列表渲染的应用场景,所有需要重复视图的地方都可以使用列表渲染,例如:swiper

javascript 复制代码
<swiper 
  indicator-dots
  indicator-color="#fff"
  indicator-active-color="#f00"
  autoplay
  >
  <block wx:for="{{ swiperData }}" wx:for-item="item" wx:for-index="index" wx:key="index">
    <swiper-item>
      <image mode="widthFix" style="width: 100%;" src="{{ item }}"></image>
    </swiper-item>
  </block>
</swiper>
javascript 复制代码
Page({
  data: {
    swiperData:[
      "../../images/1.png",
      "../../images/2.jpg",
      "../../images/3.jpg"
     ]
   }
})

1.9、模板

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

定义模板

使用 name 属性,作为模板的名字。然后在内定义代码片段

javascript 复制代码
<template name="customTemplate">
  <view class="text">{{ test }}</view>
</template>

使用模板

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

javascript 复制代码
<import src="./list/list.wxml" /> 
<view>
  <view>引用模板</view>
  <template is="customTemplate" data="{{ test }}"></template>
  <template is="customTemplate" data="{{ test }}"></template>
</view>
javascript 复制代码
Page({
  data: {
    test:"测试"
   }
})

当然也需要引入样式,来丰富模板

javascript 复制代码
.text{
  color: red;
}

引入模板样式到页面

javascript 复制代码
@import "./list/list.wxss";

1.10、模板应用

在微信小程序的项目中,同一个项目一般风格统一化,所以相同的页面效果也是常见的,此时模板的使用率就大大增多了。例如最常见的列表效果

增加列表模板

javascript 复制代码
<template name="listTemplate" >
  <view class="list">
    <block wx:for="{{ foods }}" wx:for-item="item" wx:key="id">
      <view class="item">
        <image mode="widthFix" src="{{ item.pic }}"></image>
        <text>{{ item.name }}</text>
      </view>
    </block>
  </view>
</template>
javascript 复制代码
.list{
  width: 100%;
}

.item{
  margin: 10px;
}

.list image{
  width: 100px;
}

页面应用模板

javascript 复制代码
<import src="./lists/lists" />
<template is="listTemplate" data="{{ foods }}"></template>
javascript 复制代码
@import "./lists/lists.wxss";
javascript 复制代码
Page({
  data: {
    foods: [{
        "id": 1,
        "name": "美食-甜豆干",
        "pic": "http://iwenwiki.com:3002/images/goods/1.jpg"
       },
       {
        "id": 2,
        "name": "好欢螺螺蛳粉300g*6袋",
        "pic": "http://iwenwiki.com:3002/images/goods/2.jpg"
       },
       {
        "id": 3,
        "name": "良品铺子-肉松饼380gx2袋",
        "pic": "http://iwenwiki.com:3002/images/goods/3.webp"
       }
     ]
   }
})
相关推荐
2501_916007472 小时前
iOS APP 开发,从项目创建、证书与描述文件配置、安装测试和IPA 上传
android·ios·小程序·https·uni-app·iphone·webview
CHU7290352 小时前
淘宝扭蛋机小程序前端功能详解:以交互设计赋能趣味体验
java·前端·小程序·php
CHU72903520 小时前
安心陪伴,便捷就医:陪诊代办小程序的温暖设计
前端·小程序·php
CHU72903521 小时前
线上扭蛋机拆盒小程序前端功能版块解析
前端·小程序·php
深海蓝山1 天前
基于Canvas的原生签名组件,兼容小程序和H5
小程序·canvas·签名
毕设源码-邱学长1 天前
【开题答辩全过程】以 基于微信小程序的课程表信息系统的开发实现为例,包含答辩的问题和答案
微信小程序·小程序
CHU7290351 天前
线上美容预约小程序:开启便捷美肤新方式
小程序
编程、小哥哥1 天前
物业小程序(业主端+物业端)功能逻辑图与原型图
小程序