Skip to content

WXML template

WXML stands for WeiXin Markup Language, a markup language designed for the WeChat Mini Program framework. Combined with the basic components and event system of the Mini Program, it can be used to build the structure of a page.
Open the editor of the development tool, find the app.json file in the root directory, double-click to open it, add a new line 'pages/wxml/index' to 'pages/index/index' and save the file. After the simulator is refreshed, readers can find the pages/wxml/index.wxml file in the editor. The study of this summary is completed by modifying this file.

Introduction

The suffix of the WXML file is .wxml. Open the pages/wxml/index.wxml file. Readers who have experience in HTML development should be familiar with this way of writing code. Simple WXML statements are very similar to HTML in syntax.

js
<!--pages/wxml/index.wxml-->

<text>pages/wxml/index.wxml</text>
The basic syntax of WXML without any logical functions is as follows:
js
<!-- Add comment here-->

<Tag name Attribute name 1="Attribute value 1" Attribute name 2="Attribute value 2" ...> ...</Tag name>
A complete WXML statement consists of a start tag and an end tag. The tags can be content or other WXML statements. This is consistent with HTML. The difference is that WXML requires tags to be strictly closed. Failure to close will result in compilation errors, as shown in the following code:
js
<text>hello world
<!--
text is not closed, resulting in a compile error:
VM148:2 ./pages/wxml/index.wxml
 end tag missing, near text
> 1 | <text>hello world
    | ^
-->
Tags can have attributes, which provide more information about WXML elements. Attributes are always defined in the start tag. Except for some special attributes, the format of other attributes is key='value' in pairs. It should be noted that the attributes in WXML are case-sensitive, that is, class and Class are different attributes in WXML. The following code is an example of a text tag.
js
<!-- A simple text tag-->
<text>hello world</text>

<!-- view contains text tags -->
<view>
  <text>hello world</text>
</view>
An example of an image tag with attributes is as follows:
js
<image class="userinfo-avatar" src="./image/a.png" ></image>

Data Binding

The user interface presentation may vary due to different data at the current moment, or due to dynamic changes in user operations. This requires the ability to dynamically change the rendering interface during the program's operation. In Web development, developers use JavaScript to complete real-time updates of the interface through the Dom interface. In the applet, the data binding function provided by the WXML language is used to complete this function.
Let's take a look at a simple example first.
Make some simple changes to the content of the pages/wxml/index.wxml file, as shown in the following code:
js
<!--pages/wxml/index.wxml-->
<text>Current time: {{time}}</text>
After saving, the tool refreshes, and the simulator does not display the current time. This is because we have not set any initial value for time. Please open the pages/wxml/index.js file and add: time: (new Date()).toString() in the curly braces of data, as shown in the following code:
js
// pages/wxml/index.js
Page({
  /**
   * Initial page data
   */
  data: {
    time: (new Date()).toString()
  },
})
Save, the simulator will correctly display the current time after refreshing, and the time will be updated every time it is compiled.
WXML uses {{variable name}} to bind the data object properties in the WXML file and the corresponding JavaScript file.
In order to keep it simple, the following format is used to show the above code logic. The first paragraph of comments is used to indicate the data structure in the script file corresponding to WXML, as shown in the following code:
js
<!--
{
  time: (new Date()).toString()
}
-->
<text> Current time: {{time}}/text>
Attribute values ​​can also be changed dynamically, but the difference is that the attribute value must be enclosed in double quotes, as shown in the following code:
js
<!-- Correct coding -->
<text data-test="{{test}}"> hello world</text>


<!-- Wrong coding  -->
<text data-test={{test}}> hello world </text >
It should be noted that variable names are case-sensitive, which means {{name}} and {{Name}} are two different variables, as shown in the following code:
js
<!--
{
  w: 'w',
  W: 'W'
}
-->


<view>{{w}}</view>
<view>{{W}}</view>


<!-- Output
w
W
-->
It should also be noted that variables that are not defined or set to undefined will not be synchronized to wxml, as shown in the following code:
js
<!--
{
  var2: undefined,
  var3: null,
  var4: "var4"
}
-->


<view>{{var1}}</view>
<view>{{var2}}</view>
<view>{{var3}}</view>
<view>{{var4}}</view>


<!--
Output:
null
var4
-->
The concept of data binding is introduced in more detail in Chapter 3.

Logical syntax

The {{ variable name }} syntax can make WXML have the ability of dynamic rendering. In addition, simple logical operations can be performed within {{ }}.

Ternary operation:

js
<!-- Display page content conditionally based on whether a is equal to 10 or not -->
<text>{{ a === 10? "variable a is equal to 10": "variable a is not equal to 10"}}</text>
Arithmetic operation:
js
<!--
{ a: 1,  b: 2, c: 3 }
-->


<view> {{a + b}} + {{c}} + d </view>


<!-- Output 3 + 3 + d -->
Similar to arithmetic operation, it also supports string concatenation, as shown in the following code:
js
<!--
{ name: 'world' }
-->


<view>{{"hello " + name}}</view>


<!-- Output hello world -->
Numbers, strings, or arrays can also be placed directly in brackets, as shown in the following code:
js
<text>{{[1,2,3]}}</text>

<!-- Output 1,2,3 -->



<text>{{"hello world"}}</text>

<!-- Output hello world -->

Conditional logic

In WXML, use wx:if="{{condition}}" to determine whether the code block needs to be rendered:

js
<view wx:if="{{condition}}"> True </view>
Use wx:elif and wx:else to add an else block:
js
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
Because wx:if is a control attribute, it needs to be added to a tag. If you want to judge multiple component tags at one time, you can use a <block/> tag to wrap multiple components and use the wx:if control attribute on it.
js
<block wx:if="{{true}}">
  <view> view1 </view>
  <view> view2 </view>
</block>

List Rendering

Use the wx:for control attribute on the component to bind an array, and you can use the data of each item in the array to repeatedly render the component. The default subscript variable name of the current item in the array is index, and the default variable name of the current item in the array is item, as shown in the following code:

js
<!-- `array` is an array -->
<view wx:for="{{array}}">
  {{index}}: {{item.message}}
</view>

<!-- Corresponding script file
Page({
  data: {
    array: [{
      message: 'foo',
    }, {
      message: 'bar'
    }]
  }
})
-->
Use wx:for-item to specify the variable name of the current element of the array, and use wx:for-index to specify the variable name of the current subscript of the array:
js
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
  {{idx}}: {{itemName.message}}
</view>
Similar to block wx:if, wx:for can also be used on the <block/> tag to render a structure block containing multiple nodes, as shown in the following code:
js
<block wx:for="{{[1, 2, 3]}}">
  <view> {{index}}: </view>
  <view> {{item}} </view>
</block>
If the position of the items in the list will change dynamically or new items are added to the list, and you want the items in the list to maintain their own characteristics and status (such as the input content in <input/>, the selected state of <switch/>), you need to use wx:key to specify the unique identifier of the item in the list.
The value of wx:key is provided in two forms:
1. A string representing a property of item in the array of the for loop. The value of the property needs to be a unique string or number in the list and cannot be changed dynamically.
2. The reserved keyword this represents the item itself in the for loop. This representation requires the item itself to be a unique string or number, such as:
When data changes trigger the rendering layer to re-render, the components with key will be corrected, and the framework will ensure that they are reordered instead of recreated to ensure that the components maintain their own state and improve the efficiency of list rendering, as shown in the following code:
js
<switch wx:for="{{objectArray}}" wx:key="unique" > {{item.id}} </switch>
<button bindtap="switch"> Switch </button>
<button bindtap="addToFront"> Add to the front </button>


<switch wx:for="{{numberArray}}" wx:key="*this" > {{item}} </switch>
<button bindtap="addNumberToFront"> Add Number to the front </button>
js
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
    })
  }
})

Template

WXML provides templates (template), you can define code snippets in the template, and then call the name attribute in different places as the name of the template and then define the code snippet in <template/>, as shown in the following code:

js
<template name="msgItem">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view>
</template>
Use the is attribute to declare the template to be used, and then pass the data required by the template, as shown in the following code:
js
<!--
item: {
  index: 0,
  msg: 'this is a template',
  time: '2016-06-18'
}
-->


<template name="msgItem">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view>
</template>


<template is="msgItem" data="{{...item}}"/>

<!-- Output
0: this is a template Time: 2016-06-18
-->
Use is to dynamically determine which template needs to be rendered, as shown in the following code:
js

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



<!-- Output
odd
even
odd
even
odd
-->

Reference

WXML provides two file reference methods: import and include.

Import can use the template defined in the target file in the file, such as: a template called item is defined in item.wxml.
js
<!-- item.wxml -->
<template name="item">
  <text>{{text}}</text>
</template>
If item.wxml is referenced in index.wxml, the item template can be used:
js
<import src="item.wxml"/>

<template is="item" data="{{text: 'forbar'}}"/>
It should be noted that import has the concept of scope, that is, only the template defined in the target file will be imported, and the template imported in the target file will not be imported. In short, import does not have the recursive feature.
For example: C references B, B references A, the template defined by B can be used in C, and the template defined by A can be used in B, but C cannot use the template defined by A, as shown in the following code:
js
<!-- A.wxml -->
<template name="A">
  <text> A template </text>
</template>
js
<!-- B.wxml --><import src="a.wxml"/><template name="B">  <text> B template </text></template>
js
<!-- C.wxml -->
<import src="b.wxml"/>

<template is="A"/>  <!-- A warning will be triggered here because template A is not defined in b -->

<template is="B"/>
Include can introduce the entire code in the target file except <template/> <wxs/>, which is equivalent to copying it to the include position, as shown in the following code:
js
<!-- index.wxml -->
<include src="header.wxml"/>

<view> body </view>

<include src="footer.wxml"/>
js
<!-- header.wxml -->
<view> header </view>
js
<!-- footer.wxml -->
<view> footer </view>

Common attributes

The attributes supported by all wxml tags are called common attributes, as shown in the following table.
Property name
Type
Description
Annotation
id
String
Unique identifier of component
Unique for the entire page
class
String
Style class of component
Style class defined in the corresponding WXSS
style
String
Inline style of component
Inline style that can be set dynamically
hidden
Boolean
Whether the component is displayed
All components are displayed by default
data-*
Any
Custom attribute
When an event is triggered on a component, it will be sent to the event processing function
bind*/catch*
EventHandler
Event of component
-