Unexpected token
or Unexpected token: "tokenName", may be reserved words.
.<!--WXML--><view>{{ message }}</view>
// page.jsPage({data: {message: 'Hello MINA!',},})
<!--WXML--><view wx:for="{{array}}">{{item}}</view>
// page.jsPage({data: {array: [1, 2, 3, 4, 5],},})
<!--WXML--><view wx:if="{{view == 'WEBVIEW'}}">WEBVIEW</view><view wx:elif="{{view == 'APP'}}">APP</view><view wx:else="{{view == 'MINA'}}">MINA</view>
// page.jsPage({data: {view: 'MINA',},})
<!--WXML--><template name="staffName"><view>FirstName: {{firstName}}, LastName: {{lastName}}</view></template><template is="staffName" data="{{...staffA}}"></template><template is="staffName" data="{{...staffB}}"></template><template is="staffName" data="{{...staffC}}"></template>
// page.jsPage({data: {staffA: { firstName: 'Hulk', lastName: 'Hu' },staffB: { firstName: 'Shang', lastName: 'You' },staffC: { firstName: 'Gideon', lastName: 'Lin' },},})
<view bindtap="add">{{count}}</view>
Page({data: {count: 1,},add(e) {this.setData({count: this.data.count + 1,})},})
<view>{{ message }}</view>
Page({data: {message: 'Hello MINA!',},})
<view id="item-{{id}}"></view>
Page({data: {id: 0,},})
<view wx:if="{{condition}}"></view>
Page({data: {condition: true,},})
true
: A boolean type true, representing a truth value.false
: A boolean type false, representing a falsehood value.checked="false"
, as its computed result is a string, which when converted to a boolean type, represents a truth value.<view hidden="{{flag ? true : false}}">Hidden</view>
<view>{{a + b}} + {{c}} + d</view>
Page({data: {a: 1,b: 2,c: 3,},})
<view wx:if="{{length > 5}}"></view>
<view>{{"hello" + name}}</view>
Page({data: {name: 'MINA',},})
<view>{{object.key}} {{array[0]}}</view>
Page({data: {object: {key: 'Hello ',},array: ['MINA'],},})
<view wx:for="{{[zero, 1, 2, 3, 4]}}">{{item}}</view>
Page({data: {zero: 0,},})
<template is="objectCombine" data="{{for: a, bar: b}}"></template>
Page({data: {a: 1,b: 2,},})
{for: 1, bar: 2}
...
.<template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}"></template>
Page({data: {obj1: {a: 1,b: 2,},obj2: {c: 3,d: 4,},},})
{a: 1, b: 2, c: 3, d: 4, e: 5}
.<template is="objectCombine" data="{{foo, bar}}"></template>
Page({data: {foo: 'my-foo',bar: 'my-bar',},})
{foo: 'my-foo', bar:'my-bar'}
.<template is="objectCombine" data="{{...obj1, ...obj2, a, c: 6}}"></template>
Page({data: {obj1: {a: 1,b: 2,},obj2: {b: 3,c: 4,},a: 5,},})
{a: 5, b: 3, c: 6}
.<view wx:for="{{[1,2,3]}} ">{{item}}</view>
<view wx:for="{{[1,2,3] + ' '}}">{{item}}</view>
wx:for
control attribute on a component and binding it to an array, one can utilize the data from each item in the array to render the component repetitively.index
, and the variable name for the current item in the array is item
.<view wx:for="{{array}}">{{index}}: {{item.message}}</view>
Page({data: {array: [{message: 'foo',},{message: 'bar',},],},})
wx:for-item
, one can designate the variable name for the current element in the array.wx:for-index
, one can specify the variable name for the current index of the array:<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">{{idx}}: {{itemName.message}}</view>
wx:for
can also be nested, as demonstrated in the following multiplication table of nine:<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i"><view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j"><view wx:if="{{i <= j}}">{{i}} * {{j}} = {{i * j}}</view></view></view>block wx:for
block wx:if
, wx:for
can also be used on a <block/>
tag to render a structure block containing multiple nodes. For instance:<block wx:for="{{[1, 2, 3]}}"><view>{{index}}:</view><view>{{item}}</view></block>
<input>
, or the selected state of <switch>), it becomes necessary to use wx:key
to specify the unique identifier for the items within the list.wx:key
is provided in two forms.*this
represents the item itself within the for loop. This representation requires the item itself to be a unique string or number, as shown:wx:key
is not provided, a warning
will be issued. However, if it is known with certainty that the list is static, or the order is not of concern, this warning can be disregarded.<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;">{{item.id}}</switch><button bindtap="switch">Switch</button><button bindtap="addToFront">Add to the front</button><switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;">{{item}}</switch><button bindtap="addNumberToFront">Add to the front</button>
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(e) {const length = this.data.objectArray.lengthfor (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(e) {const length = this.data.objectArray.lengththis.data.objectArray = [{ id: length, unique: 'unique_' + length }].concat(this.data.objectArray)this.setData({objectArray: this.data.objectArray,})},addNumberToFront(e) {this.data.numberArray = [this.data.numberArray.length + 1].concat(this.data.numberArray)this.setData({numberArray: this.data.numberArray,})},})
<view wx:for="{{[1,2,3]}} ">{{item}}</view>
<view wx:for="{{[1,2,3] + ' '}}">{{item}}</view>
wx:if="{{condition}}"
is used to determine whether the code block needs to be rendered:<view wx:if="{{condition}}">True</view>
wx:elif
and wx:else
to add an else block:<view wx:if="{{length > 5}}">1</view><view wx:elif="{{length > 2}}">2</view><view wx:else>3</view>
wx:if
is a control attribute, it needs to be added to a tag. If multiple component tags need to be evaluated simultaneously, a <block/>
tag can be used to encapsulate these components, with the wx:if
control attribute applied on top.<block wx:if="{{true}}"><view>view1</view><view>view2</view></block>
<block/>
is not a component, but merely a wrapping element. It does not render anything on the page and only accepts control attributes.wx:if
vs hidden
wx:if
switches, the framework undergoes a partial rendering process. This ensures that the condition block is either destroyed or re-rendered during the switch.wx:if
is also lazy. If the initial rendering condition is false
, the framework does nothing. It only begins partial rendering when the condition turns true for the first time.hidden
is much simpler. The component is always rendered, it merely controls its visibility, toggling between display and concealment.wx:if
incurs a higher switching cost, while hidden
has a higher initial rendering cost. Therefore, hidden
is more suitable for scenarios requiring frequent switching, whereas wx:if
is preferable when the conditions are unlikely to change during runtime.<template/>
, as follows:<!--index: intmsg: stringtime: string--><template name="msgItem"><view><text>{{index}}: {{msg}}</text><text>Time: {{time}}</text></view></template>
<template is="msgItem" data="{{...item}}" />
Page({data: {item: {index: 0,msg: 'this is a template',time: '2016-09-15',},},})
<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>
<wxs />
module defined within the template definition file.bindtap
, when the user clicks on the component, the corresponding event handling function will be located within the respective Page of the interface.<view id="tapTest" data-hi="WeChat" bindtap="tapName">Click me!</view>
Page({tapName(event) {console.log(event)},})
{"type": "tap","timeStamp": 895,"target": {"id": "tapTest","dataset": {"hi": "WeChat"}},"currentTarget": {"id": "tapTest","dataset": {"hi": "WeChat"}},"detail": {"x": 53,"y": 14},"touches": [{"identifier": 0,"pageX": 53,"pageY": 14,"clientX": 53,"clientY": 14}],"changedTouches": [{"identifier": 0,"pageX": 53,"pageY": 14,"clientX": 53,"clientY": 14}]}
event.instance
object. The second parameter is ownerInstance
, which, like event.instance
, is a ComponentDescriptor
object. The specific usage is as follows:<wxs module="wxs" src="./test.wxs"></wxs><view id="tapTest" data-hi="TMF" bindtap="{{wxs.tapName}}">Click me!</view>Note: The bound WXS function must be enclosed within {{}}
function tapName(event, ownerInstance) {console.log('tap wechat', JSON.stringify(event))}module.exports = {tapName,}
ownerInstance
includes several methods that can be used to set the component's style and class. For detailed information on the methods included and the reasons for using WXS functions to respond to events, please click to view more details.Types | Trigger condition |
touchstart | Initiation of finger touch action |
touchmove | Movement after finger touch |
touchcancel | Interruption of finger touch action, such as call reminders, pop-up notifications. |
touchend | Termination of finger touch action |
tap | Immediate departure after finger touch |
longpress | Upon finger touch, if the departure occurs after more than 350ms and an event callback function has been specified and triggered, the tap event will not be activated. |
longtap | Upon finger touch, if the departure occurs after more than 350ms (it is recommended to use the longpress event instead). |
transitionend | Triggered upon the conclusion of a WXSS transition or wx.createAnimation animation. |
animationstart | Triggered at the commencement of a WXSS animation. |
animationiteration | Triggered at the conclusion of a single iteration of a WXSS animation. |
animationend | Triggered upon the completion of a WXSS animation. |
touchforcechange | On iPhone devices that support 3D Touch, it is triggered by a firm press. |
bindtap
, catchtouchstart
. In non-native components, 'bind' and 'catch' can be immediately followed by a colon without changing their meaning, such as bind:tap
, catch:touchstart
.bind
event binding does not prevent the bubbling event from propagating upwards, while catch
event binding can halt the upward propagation of a bubbling event.handleTap3
and handleTap2
(as the tap event will bubble up to the middle view, and the middle view prevents the tap event from bubbling up, no longer passing it to the parent node). Clicking on the middle view will trigger handleTap2
, and clicking on the outer view will trigger handleTap1
.<view id="outer" bindtap="handleTap1">outer view<view id="middle" catchtap="handleTap2">middle view<view id="inner" bindtap="handleTap3">inner view</view></view></view>
handleTap2
, handleTap4
, handleTap3
, and handleTap1
.<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">outer view<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">inner view</view></view>
capture-bind
in the above code is changed to capture-catch
, only handleTap2
will be triggered.<view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2">outer view<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">inner view</view></view>
Attributes | Types | Note |
type | string | Event type |
timeStamp | interger | Timestamp of when the event was generated |
target | object | Collection of attribute values of the component triggering the event |
currentTarget | object | Collection of attribute values of the current component |
Attributes | Types | Note |
detail | object | Additional information |
Attributes | Types | Note |
touches | array | TouchEvent, an array of information about touch points currently remaining on the screen |
changedTouches | array | TouchEvent, an array of information about touch points currently undergoing changes |
<canvas>
The touch events within it do not bubble, hence there is no currentTarget.Attributes | Types | Note |
id | string | The id of the source component of the event |
tagName | string | The type of the current component |
object | The collection of custom attributes on the source component of the event, beginning with data- |
Attributes | Types | Note |
id | string | The id of the current component |
tagName | string | The type of the current component |
object | The collection of custom attributes on the current component, beginning with data- |
data-
, link multiple words with a hyphen-
, uppercase is not supported (it will be automatically converted to lowercase), such as data-element-type
. Ultimately, in event.currentTarget.dataset
, the hyphen will be converted to camel caseelementType
.<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap">DataSet Test</view>
Page({bindViewTap(event) {event.currentTarget.dataset.alphaBeta === 1 // - will be converted to camel case notationevent.currentTarget.dataset.alphabeta === 2 // Uppercase will be converted to lowercase},})
Attributes | Types | Note |
identifier | number | Identifier of the touch point |
pageX,pageY | number | The distance from the top left corner of the document, with the top left corner of the document as the origin, the X-axis running horizontally, and the Y-axis running vertically. |
clientX,clientY | number | The distance from the top left corner of the page's visible area (the screen excluding the navigation bar), with the X-axis running horizontally and the Y-axis running vertically. |
Attributes | Types | Note |
identifier | number | Identifier of the touch point |
x, y | number | The distance from the top left corner of the Canvas, with the top left corner of the Canvas as the origin, the X-axis running horizontally, and the Y-axis running vertically. |
ComponentDescriptor
instance. For interactive animations, setting style and class is sufficient. An example of a WXS function is as follows:const wxsFunction = function(event, ownerInstance) {const instance = ownerInstance.selectComponent('.classSelector') // Returns the instance of the componentinstance.setStyle({'font-size': '14px', // Supports rpx})instance.getDataset()instance.setClass(className)// ...return false // Prevents further propagation, equivalent to simultaneously calling stopPropagation and preventDefault}
event.instance
representing the ComponentDescriptor
instance of the component that triggered the event. The ownerInstance
represents the ComponentDescriptor
instance of the component in which the event-triggering component resides. If the event-triggering component is within a page, the ownerInstance
represents the page instance.ComponentDescriptor
is as follows:Method | Category | Description |
selectComponent | Selector Object | Returns an instance of the ComponentDescriptor for the component. |
selectAllComponents | Array of Selector Objects | Returns an array of ComponentDescriptor instances for the component. |
setStyle | Object/string | Establishes the component's style, supporting rpx. The style set here takes precedence over the style defined within the component's WXML. However, it is unable to establish the style for the top-level page. |
addClass/removeClass/ hasClass | String | Establishes the class of the component. The class set here takes precedence over the class defined within the component's WXML. However, it is unable to establish the class for the top-level page. |
getDataset | - | Returns the dataset object of the current component/page. |
callMethod | (funcName:string, args:object) | Invokes the function defined in the logic layer (App Service) of the current component/page. Here, 'funcName' represents the function name, while 'args' represents the function's parameters. |
requestAnimationFrame | Function | Similar to the native requestAnimationFrame. It is used for setting animations. |
getState | - | Returns an object. This method is utilized when there are local variables that need to be stored for subsequent use. |
triggerEvent | (eventName, detail) | Consistent with the component's triggerEvent. |
callMethod
is a method within WXS for invoking the code of the logic layer (App Service) developer, while WxsPropObserver
is a mechanism for the code of the logic layer (App Service) developer to invoke WXS logic.<wxs module="test" src="./test.wxs"></wxs><viewchange:prop="{{test.propObserver}}"prop="{{propValue}}"bindtouchmove="{{test.touchmove}}"class="movable"></view>
change:prop
(with the prefix 'change:' preceding the property) triggers the WXS function when the prop attribute is set. The value must be enclosed within {{}}
. This is similar to the observer attribute defined in the properties of a Component, which is triggered after setData({propValue: newValue})
is invoked.{{}}
. The WXS function is triggered when the value of prop is set, not just when the value changes. Therefore, the WxsPropObserver
function will be invoked once during page initialization.module.exports = {touchmove(event, instance) {console.log('log event', JSON.stringify(event))},propObserver(newValue, oldValue, ownerInstance, instance) {console.log('prop observer', newValue, oldValue)},}
import
and include
.import
allows the use of the template
defined in the target file, as follows:template
named item
is defined in item.wxml:<!-- item.wxml --><template name="item"><text>{{text}}</text></template>
item
template can be utilized:<import src="item.wxml" /><template is="item" data="{{text: 'forbar'}}" />
template
defined in B, and B can utilize the template
defined in A. However, C cannot utilize the template
defined in A.<!-- A.wxml --><template name="A"><text>A template</text></template>
<!-- B.wxml --><import src="a.wxml" /><template name="B"><text>B template</text></template>
<!-- C.wxml --><import src="b.wxml" /><template is="A" /><!-- Error! Can not use tempalte when not import A. --><template is="B" />
Include
can import the entire code of the target file, excluding <template/>
and <wxs/>
, essentially copying it to the include
location, as follows:<!-- index.wxml --><include src="header.wxml" /><view>body</view><include src="footer.wxml" />
<!-- header.wxml --><view>header</view>
<!-- footer.wxml --><view>footer</view>
Was this page helpful?