从0到一开发微信小程序(5)—小程序WXML

其他相关文章

从0到一开发微信小程序(1)——申请账号并安装开发环境
从0到一开发微信小程序(2)——开发第一个小程序
从0到一开发微信小程序(3)—小程序框架配置
从0到一开发微信小程序(4)—小程序组件
从0到一开发微信小程序(5)—小程序WXML
从0到一开发微信小程序(6)—小程序常用API ——正在书写中
从0到一开发微信小程序(7)—小程序组件库(提高开发效率)
从0到一开发微信小程序(8)—实战一个商城项目——正在书写中

1、WXML

首先,我们得看看wxml是什么?

WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。

1.1、事件

1.1.1、系统

什么是事件?

  • 事件是视图层到逻辑层的通讯方式。
  • 事件可以将用户的行为反馈到逻辑层进行处理。
  • 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
  • 事件对象可以携带额外信息,如 id, dataset, touches。

怎么使用呢?

  • 在组件中绑定一个事件处理函数。

如bindtap,当用户点击该组件的时候会在该页面对应的 Page 中找到相应的事件处理函数。
测试代码:

<view id="tapTest" data-hi="Weixin" bindtap="tapName"> Click me! </view>
Page({
    
    
  tapName: function(event) {
    
    
    console.log(event)
  }
})

展示效果:
在这里插入图片描述

点击之后,控制栏会出现:
在这里插入图片描述

上图中各个属性值的详细分析如下:

属性 类型 说明
type String 事件类型
timeStamp Integer 事件生成时的时间戳
target Object 触发事件的组件的一些属性值集合
currentTarget Object 当前组件的一些属性值集合
mark Object 事件标记数据
detail Object 额外的信息
touches Array 触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouches Array 触摸事件,当前变化的触摸点信息的数组

1.1.2、分类

事件主要分类为两个种:一种是冒泡事件,一种是非冒泡事件:

  1. 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
  2. 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。

1.1.2.1、冒泡事件(bindtap)

  • WXML的冒泡事件列表:
类型 触发条件
touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
touchend 手指触摸动作结束
tap 手指触摸后马上离开
longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发
longtap 手指触摸后,超过350ms再离开(推荐使用 longpress 事件代替)
transitionend 会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart 会在一个 WXSS animation 动画开始时触发
animationiteration 会在一个 WXSS animation 一次迭代结束时触发
animationend 会在一个 WXSS animation 动画完成时触发
touchforcechange 在支持 3D Touch 的 iPhone 设备,重按时会触发

测试用例:

<view bindtap="bindParentBubbleHandle">
  <button type="primary" bindtap="bindChildBubbleHandle">冒泡事件</button>
</view>
Page({
    
    
  bindParentBubbleHandle(){
    
    
    console.log("父级冒泡事件");
   },
  bindChildBubbleHandle(){
    
    
    console.log("子级冒泡事件");
   }
})

展示效果:
在这里插入图片描述

点击冒泡事件,控制台展示为:
在这里插入图片描述

1.1.2.2、非冒泡事件(catchtap)

测试用例:

<view catchtap="catchParentBubbleHandle">
  <button type="primary" catchtap="catchChildBubbleHandle">非冒泡事件</button>
</view>
  catchParentBubbleHandle(){
    
    
    console.log("非冒泡父级事件");
   },
  catchChildBubbleHandle(){
    
    
    console.log("非冒泡子级事件");
   }

展示效果:
在这里插入图片描述

点击非冒泡事件,控制台展示为:
在这里插入图片描述

1.1.3、携带参数

1.1.3.1、currentTarget 携带参数

  • 在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。
属性 类型 说明
id String 当前组件的id
dataset Object 当前组件上由data-开头的自定义属性组成的集合

测试代码:

<view data-id="1001" bindtap="bindViewTap"> 携带参数 </view>

Page({
    
    
  bindViewTap(e){
    
    
    console.log(e.currentTarget.dataset.id);
   }
})

展示效果:
在这里插入图片描述

当我们点击携带参数,会发现控制栏会出现
在这里插入图片描述

说明我们e.currentTarget.dataset.id获取到了id的值
温馨提示
在wxml中添加数据的时候,必须在自定义属性前添加data-*

1.1.3.2、mark读取携带参数

  • 可以使用 mark 来识别具体触发事件的 target 节点。此外, mark 还可以用于承载一些自定义数据(类似于 dataset )。
  • 当事件触发时,事件冒泡路径上所有的 mark 会被合并,并返回给事件回调函数。(即使事件不是冒泡事件,也会 mark 。)

测试代码:

<view mark:parentMark="父级" bindtap="bindMarkTap">
    <button type="primary" mark:childMark="子级" bindtap="bindButtonTap">mark读取携带参数</button>
</view>
bindMarkTap(e) {
    
    
    console.log(e.mark);
  },
  bindButtonTap(e) {
    
    
    console.log(e.mark);
  }

展示效果:
在这里插入图片描述

点击mark读取携带参数会发现控制栏出现:
在这里插入图片描述

mark 和 dataset 很相似,主要区别在于: mark 会包含从触发事件的节点到根节点上所有的 mark: 属性值;而 dataset 仅包含一个节点的 data- 属性值。
细节注意事项:

  • 如果存在同名的 mark ,父节点的 mark 会被子节点覆盖。
  • 在自定义组件中接收事件时, mark 不包含自定义组件外的节点的 mark 。
  • 不同于 dataset ,节点的 mark 不会做连字符和大小写转换。

1.1.3.3、dataset

在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。
在 WXML 中,这些自定义数据以 data- 开头,多个单词由连字符 - 连接。这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如:

  • data-element-type ,最终会呈现为 event.currentTarget.dataset.elementType ;
  • data-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype 。

示例:

<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>
Page({
    
    
  bindViewTap:function(event){
    
    
    event.currentTarget.dataset.alphaBeta === 1 // - 会转为驼峰写法
    event.currentTarget.dataset.alphabeta === 2 // 大写会转为小写
  }
})

1.2、条件

条件判断,相信大家只要玩过后端的基本都知道吧,前端vue也是如此。

1.2.1、wx:if(如果)

<view wx:if="{
     
     { flag }}">你帅吗</view>
Page({
    
    
  data: {
    
    
    flag:true  //展示
   }
})

展示效果:
在这里插入图片描述

1.2.2、wx:else(那么)

<view wx:if="{
     
     { flag }}">我帅</view>
<view wx:else="{
     
     { flag }}">你丑</view>
Page({
    
    
  data: {
    
    
    flag:true  //展示
   }
})

展示效果:
在这里插入图片描述

1.2.3、wx:elif(如果那么)

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

展示效果:
在这里插入图片描述

1.2.4、hidden(隐藏)

  • hidden 与wx:if类似,同样可以来判断是否需要渲染该代码块
<view hidden="{
     
     { hidden }}">果子熟了</view>
Page({
    
    
  data: {
    
    
    hidden:true
   }
})

展示效果为空,因为已经隐藏了。

1.2.5、总结(wx:if vs hidden 区别)

因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的基于CSS控制显示与隐藏。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好

1.3、列表渲染–循环遍历

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

基本使用

默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
测试代码:

<view>
  <view wx:for="{
     
     { moves }}">{
   
   { item }}</view>
</view>

Page({
    
    
  data: {
    
    
    moves:["西游记","三国演义","爱情公寓"]
   }
})

展示效果:
在这里插入图片描述

带下标输出的使用

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

测试代码:

<view>
  <view wx:for="{
     
     { moves }}" wx:for-item="move" wx:for-index="id">{
   
   {id}}-{
   
   { move }}</view>
</view>

Page({
    
    
  data: {
    
    
    moves:["西游记","三国演义","爱情公寓"]
   }
})

展示效果:
在这里插入图片描述

复杂数据(Json)

<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>
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.3.1、wx:key(唯一标识符)

  • 如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态,需要使用 wx:key 来指定列表中项目的唯一的标识符
  • 当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率

温馨提示:
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略
在这里插入图片描述

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

测试用例:

<view>
  <button type="primary" bindtap="clickHandle">增加数据</button>
  <block wx:for="{
     
     { result }}" wx:for-item="item"  wx:key="id">
    <view>{
   
   { item.name }}</view>
    <image src="{
     
     { item.pic }}"></image>
    <view>{
   
   { item.description }}</view>
    <view>{
   
   { item.price }}</view>
    <view>{
   
   { item.city }}</view>
  </block>
</view>
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": "北京"
      }
    ]
  },
  clickHandle(){
    
    
    this.setData({
    
    
      result:this.data.result.concat({
    
    
        "id":"3",
        "name": "对夹",
        "pic": "http://iwenwiki.com:3002/images/goods/1.jpg",
        "description": "津津卤汁豆腐干苏州特产豆干零食素食老字号食品豆制品小吃90g*10",
        "price": "39.90",
        "type": 0,
        "buynum": "435",
        "city": "北京"
       })
     })
   }
})

展示效果:
最下面一条数据为:
在这里插入图片描述
在这里插入图片描述
当点击增加数据之后,会增加一条数据展示:
在这里插入图片描述

1.3.2、应用

  • 轮播图
  • 查询页面

轮播图实例:

<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>
  swiperData:[
      "http://iwenwiki.com:3002/images/goods/1.jpg",
      "http://iwenwiki.com:3002/images/goods/2.jpg",
     ]

展示效果为滑动轮播图。

1.4、模板(提高复用性)

  • 模板顾名思义就是一个可以多处使用的代码。
  • WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用

定义模板

首先总体文件结构如下:在这里插入图片描述

首先定义模板,图片中的list下面的文件就是模板,模板只有两种文件,wxml,wxss。
list.wxml的内容为:

<template name="customTemplate">
  <view class="text">{
   
   { test }}</view>
</template>

list.wxss的内容为:

.text{
    
    
  color: red;
}

真正的内容来了:
template.js文件的内容为:

Page({
    
    
  data: {
    
    
    test:"测试"
   }
})

template.wxml文件的内容为:

<import src="./list/list.wxml" /> 
<view>
  <view>引用模板</view>
  <template is="customTemplate" data="{
     
     { test }}"></template>
  <template is="customTemplate" data="{
     
     { test }}"></template>
</view>

template.wxss文件的内容为:

@import "./list/list.wxss";

展示效果:
在这里插入图片描述

模板运用(列表复用)

文件目录如下:
在这里插入图片描述

list.wxml文件的内容如下:

<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>

list.wxss文件的内容如下:

.list{
    
    
  width: 100%;
}

.item{
    
    
  margin: 10px;
}

.list image{
    
    
  width: 100px;
}

list-template.js文件的内容如下:

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"
       }
     ]
   }
})

list-template.wxml文件的内容如下:

<import src="./list/" />
<template is="listTemplate" data="{
     
     { foods }}"></template>

list-template.wxss文件的内容如下:

@import "./list/list.wxss";

展示效果为:
在这里插入图片描述

我是zhz小白,一个在互联网行业的小白,立志成为一名架构师
https://blog.csdn.net/zhouhengzhe?t=1

猜你喜欢

转载自blog.csdn.net/zhouhengzhe/article/details/126987460