tencent cloud

Feedback

WXML

Last updated: 2024-03-04 23:15:13
    WXML (WeiXin Markup Language) is a tag language designed within the framework, which, when combined with basic components and an event system, can construct the structure of a webpage.
    Note:
    Data binding in WXML cannot utilize keywords and reserved words already stipulated in the ECMAScript standard. Usage of these will prompt error messages such as Unexpected token or Unexpected token: "tokenName", may be reserved words..

    Capability Overview

    The following simple examples illustrate the capabilities of WXML. Detailed capabilities and usage methods can be viewed in the subsequent sections:
    Data Binding
    <!--WXML-->
    <view>{{ message }}</view>
    // page.js
    Page({
    data: {
    message: 'Hello MINA!',
    },
    })
    List Rendering
    <!--WXML-->
    <view wx:for="{{array}}">{{item}}</view>
    // page.js
    Page({
    data: {
    array: [1, 2, 3, 4, 5],
    },
    })
    Conditional Rendering
    <!--WXML-->
    <view wx:if="{{view == 'WEBVIEW'}}">WEBVIEW</view>
    <view wx:elif="{{view == 'APP'}}">APP</view>
    <view wx:else="{{view == 'MINA'}}">MINA</view>
    // page.js
    Page({
    data: {
    view: 'MINA',
    },
    })
    Template
    <!--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.js
    Page({
    data: {
    staffA: { firstName: 'Hulk', lastName: 'Hu' },
    staffB: { firstName: 'Shang', lastName: 'You' },
    staffC: { firstName: 'Gideon', lastName: 'Lin' },
    },
    })
    Event
    <view bindtap="add">{{count}}</view>
    Page({
    data: {
    count: 1,
    },
    add(e) {
    this.setData({
    count: this.data.count + 1,
    })
    },
    })

    Data Binding

    The dynamic data in WXML originates from the corresponding Page's data.

    Simple Binding

    To reference a variable, it is necessary to encapsulate it using Mustache syntax (double curly braces). This can be applied to:

    Content

    <view>{{ message }}</view>
    Page({
    data: {
    message: 'Hello MINA!',
    },
    })

    Component Attributes (required within double quotes)

    <view id="item-{{id}}"></view>
    Page({
    data: {
    id: 0,
    },
    })

    Control Attributes (required within double quotes)

    <view wx:if="{{condition}}"></view>
    Page({
    data: {
    condition: true,
    },
    })

    Keywords (required within double quotes)

    true: A boolean type true, representing a truth value.
    false: A boolean type false, representing a falsehood value.
    Note:
    Avoid directly writing checked="false", as its computed result is a string, which when converted to a boolean type, represents a truth value.

    Computation

    Simple computations can be performed within {{}}, supporting the following methods:

    Ternary Operation

    <view hidden="{{flag ? true : false}}">Hidden</view>

    Arithmetic Operation

    <view>{{a + b}} + {{c}} + d</view>
    Page({
    data: {
    a: 1,
    b: 2,
    c: 3,
    },
    })
    The content in the view is 3 + 3 + d.

    Logical Determination

    <view wx:if="{{length > 5}}"></view>

    String Operation

    <view>{{"hello" + name}}</view>
    Page({
    data: {
    name: 'MINA',
    },
    })

    Data Path Operation

    <view>{{object.key}} {{array[0]}}</view>
    Page({
    data: {
    object: {
    key: 'Hello ',
    },
    array: ['MINA'],
    },
    })

    Group

    One can also directly combine within Mustache to form new objects or arrays.

    Array

    <view wx:for="{{[zero, 1, 2, 3, 4]}}">{{item}}</view>
    Page({
    data: {
    zero: 0,
    },
    })
    Ultimately amalgamating into the array [0, 1, 2, 3, 4].

    Object

    <template is="objectCombine" data="{{for: a, bar: b}}"></template>
    Page({
    data: {
    a: 1,
    b: 2,
    },
    })
    The object ultimately amalgamated is {for: 1, bar: 2}
    An object can also be expanded using the spread operator ....
    <template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}"></template>
    Page({
    data: {
    obj1: {
    a: 1,
    b: 2,
    },
    obj2: {
    c: 3,
    d: 4,
    },
    },
    })
    The object ultimately amalgamated is {a: 1, b: 2, c: 3, d: 4, e: 5}.
    If the key and value of an object are identical, it can be expressed indirectly.
    <template is="objectCombine" data="{{foo, bar}}"></template>
    Page({
    data: {
    foo: 'my-foo',
    bar: 'my-bar',
    },
    })
    The object ultimately amalgamated is {foo: 'my-foo', bar:'my-bar'} .
    The aforementioned methods can be combined at will, but if there are instances of identical variable names, the latter will overwrite the former, as in:
    <template is="objectCombine" data="{{...obj1, ...obj2, a, c: 6}}"></template>
    Page({
    data: {
    obj1: {
    a: 1,
    b: 2,
    },
    obj2: {
    b: 3,
    c: 4,
    },
    a: 5,
    },
    })
    The object ultimately amalgamated is {a: 5, b: 3, c: 6} .
    If there is a space between the curly braces and the quotation marks, it will ultimately be parsed as a string.
    <view wx:for="{{[1,2,3]}} ">
    {{item}}
    </view>
    Equivalent to:
    <view wx:for="{{[1,2,3] + ' '}}">
    {{item}}
    </view>

    List Rendering

    wx:for

    By using the 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.
    By default, the variable name for the current index of the array is 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',
    },
    ],
    },
    })
    By utilizing wx:for-item, one can designate the variable name for the current element in the array.
    By employing 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
    Similar to 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>

    wx:key

    Should the position of items within the list dynamically change, or new items be added to the list, and it is desired for the items in the list to maintain their unique characteristics and states (such as the input content in <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.
    The value of wx:key is provided in two forms.
    A string, representing a certain property of the item in the array of the for loop. The value of this property needs to be a unique string or number within the list, and it must remain static.
    The reserved keyword *this represents the item itself within the for loop. This representation requires the item itself to be a unique string or number, as shown:
    When data changes trigger a re-rendering of the rendering layer, components with keys will be adjusted. The framework ensures that they are re-ordered rather than recreated, maintaining the components' own states and enhancing efficiency during list rendering.
    If 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.
    Sample Code:
    <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.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(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(e) {
    this.data.numberArray = [this.data.numberArray.length + 1].concat(
    this.data.numberArray
    )
    this.setData({
    numberArray: this.data.numberArray,
    })
    },
    })
    If there is a space between the curly braces and the quotation marks, it will ultimately be parsed as a string.
    <view wx:for="{{[1,2,3]}} ">
    {{item}}
    </view>
    Equivalent to:
    <view wx:for="{{[1,2,3] + ' '}}">
    {{item}}
    </view>

    Conditional Rendering

    wx:if

    In the framework, wx:if="{{condition}}" is used to determine whether the code block needs to be rendered:
    <view wx:if="{{condition}}">True</view>
    One can also use 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>

    block wx:if

    As 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
    Since the template within wx:if may also contain data binding, when the condition value of 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.
    Simultaneously, 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.
    In contrast, hidden is much simpler. The component is always rendered, it merely controls its visibility, toggling between display and concealment.
    Generally speaking, 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

    WXML provides templates, allowing for the definition of code snippets within the template, which can then be invoked in various locations.

    Define CPT

    Utilize the name attribute as the template's identifier. Then, define the code snippets within the <template/>, as follows:
    <!--
    index: int
    msg: string
    time: string
    -->
    <template name="msgItem">
    <view>
    <text>{{index}}: {{msg}}</text>
    <text>Time: {{time}}</text>
    </view>
    </template>

    Apply

    Employ the 'is' attribute to declare the required template, then pass the necessary data into the template, as follows:
    <template is="msgItem" data="{{...item}}" />
    Page({
    data: {
    item: {
    index: 0,
    msg: 'this is a template',
    time: '2016-09-15',
    },
    },
    })
    The 'is' attribute can employ Mustache syntax to dynamically determine which template specifically needs to be rendered:
    <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>

    Template Scope

    The template possesses its own scope, and can only utilize data passed in, as well as the <wxs /> module defined within the template definition file.

    Event

    What is an Event?

    Events serve as a communication method from the view layer to the logic layer.
    Events can relay user actions back to the logic layer for processing.
    Events can be bound to components, and when the conditions to trigger the event are met, the corresponding event handling function in the logic layer will be executed.
    The event object can carry additional information, such as id, dataset, and touches.

    The usage of Events

    Bind an event handling function within a component.
    For instance, 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>
    Define the corresponding event handling function within the respective Page, with 'event' as the parameter.
    Page({
    tapName(event) {
    console.log(event)
    },
    })
    The information logged can be roughly observed as follows:
    {
    "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
    }
    ]
    }

    Responding to events using WXS functions

    WXS functions accept two parameters. The first one is 'event', which is based on the original event and includes an additional event.instance object. The second parameter is ownerInstance, which, like event.instance, is a ComponentDescriptor object. The specific usage is as follows:
    Bind and register the WXS functions for event handling within the component.
    <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 {{}}
    Implementation of the tapName function in the test.wxs file
    function tapName(event, ownerInstance) {
    console.log('tap wechat', JSON.stringify(event))
    }
    module.exports = {
    tapName,
    }
    The 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.

    Detailed Explanation of Events

    Classification of Events

    Events are categorized into two types: bubbling events and non-bubbling events:
    Bubbling Events: When an event is triggered on a component, the event is propagated to its parent node.
    Non-bubbling Events: When an event is triggered on a component, the event does not propagate to its parent node.
    List of Bubbling Events in WXML:
    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.
    Note:
    Apart from the events listed in the table above, custom events for other components are non-bubbling events unless otherwise specified, such as the submit event for <form/>, the input event for <input/>, and the scroll event for <scroll-view/>.

    Event Binding and Propagation

    The syntax for event binding is similar to component properties, expressed in a key-value format.
    The key begins with either 'bind' or 'catch', followed by the event type, such as 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.
    The value is a string that requires a function of the same name to be defined on the corresponding Page. Otherwise, an error will occur when the event is triggered.
    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.
    In the code below, clicking on the inner view will sequentially call 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>

    The capturing phase of the event

    Touch events support the capture phase. The capture phase precedes the bubbling phase, and during the capture phase, the order in which events reach nodes is precisely the reverse of the bubbling phase. When it is necessary to listen for events during the capture phase, the keywords 'capture-bind' or 'capture-catch' can be used, with the latter interrupting the capture phase and cancelling the bubbling phase.
    In the code below, clicking on the inner view will sequentially call 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>
    If the first 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>

    Event object

    Unless otherwise specified, when a component triggers an event, the logic layer's handler function bound to that event will receive an event object.
    BaseEvent Basic Event Object Property List:
    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
    CustomEvent custom event object attribute list (inherits from BaseEvent):
    Attributes
    Types
    Note
    detail
    object
    Additional information
    TouchEvent touch event object attribute list (inherits from BaseEvent):
    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
    Special Event: <canvas> The touch events within it do not bubble, hence there is no currentTarget.
    type
    Represents the type of the event.
    timeStamp
    The number of milliseconds elapsed from page opening to the triggering of the event.
    target
    Attributes
    Types
    Note
    id
    string
    The id of the source component of the event
    tagName
    string
    The type of the current component
    dataset
    object
    The collection of custom attributes on the source component of the event, beginning with data-
    currenTarget
    Attributes
    Types
    Note
    id
    string
    The id of the current component
    tagName
    string
    The type of the current component
    dataset
    object
    The collection of custom attributes on the current component, beginning with data-
    dataset
    Data can be defined within the component, which will be passed to the SERVICE through events. The notation is as follows: begin with 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.
    Code Example:
    <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 notation
    event.currentTarget.dataset.alphabeta === 2 // Uppercase will be converted to lowercase
    },
    })
    touches
    Touches is an array, each element being a Touch object (the touches carried in the canvas touch event are a CanvasTouch array). This represents the touch points currently remaining on the screen.

    Touch Object

    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.

    CanvasTouch Object

    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.
    changedTouches
    The data format of changedTouches is the same as touches. It represents touch points that have changed, such as from non-existence to existence (touchstart), position changes (touchmove), and from existence to non-existence (touchend, touchcancel).
    detail
    The data carried by the custom event, such as the submission event of a form component carrying user input, or the error event of a media carrying error information.
    The x and y values carried by the detail of a click event are the same as pageX and pageY, representing the distance from the top left corner of the document.
    WXS Event Response

    Example

    Effects with frequent user interaction tend to be quite laggy on mini-programs. For instance, if there are two elements A and B on a page, and the user performs a touchmove gesture on A, requiring B to move as well, <movable-view> is a typical example. The response process for a single touchmove event is as follows:
    1. The touchmove event is thrown from the view layer (Webview) to the logic layer (App Service).
    2. The logic layer (App Service) processes the touchmove event, then alters the position of B through setData.
    A single touchmove response necessitates two instances of communication between the logic and rendering layers, as well as one rendering process. The communication process is time-consuming. Moreover, the setData rendering can block the execution of other scripts, resulting in a delay in the entire user interaction animation process.

    Implementation Strategy

    The fundamental approach of this strategy is to reduce the number of communications, allowing the event to be responded to in the view layer (Webview). The mini-program framework is divided into the view layer (Webview) and the logic layer (App Service). The purpose of this layering is control; developers' code can only run in the logic layer (App Service), but this approach necessitates the execution of developers' code in the view layer (Webview).
    
    WXS functions are used to respond to mini-program events. Currently, they can only respond to built-in component events and do not support custom component events. In addition to pure logic operations, WXS functions can access and set the class and style of components through the encapsulated 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 component
    instance.setStyle({
    'font-size': '14px', // Supports rpx
    })
    instance.getDataset()
    instance.setClass(className)
    // ...
    return false // Prevents further propagation, equivalent to simultaneously calling stopPropagation and preventDefault
    }
    In this context, the parameter 'event' is an extension of the mini-program event object, with an additional 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.
    The definition of 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.
    WXS operates in the view layer (Webview), where the scope of logical events that can be performed is relatively limited. Therefore, a mechanism is required to communicate with the code of the logic layer (App Service) developer. The aforementioned 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.

    How to Use

    Event Definition in WXML:
    <wxs module="test" src="./test.wxs"></wxs>
    <view
    change:prop="{{test.propObserver}}"
    prop="{{propValue}}"
    bindtouchmove="{{test.touchmove}}"
    class="movable"
    ></view>
    The aforementioned 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.
    Note:
    The WXS function must be enclosed within {{}}. 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.
    In the WXS file test.wxs, event handling functions and functions triggered by property changes are defined and exported:
    module.exports = {
    touchmove(event, instance) {
    console.log('log event', JSON.stringify(event))
    },
    propObserver(newValue, oldValue, ownerInstance, instance) {
    console.log('prop observer', newValue, oldValue)
    },
    }
    In the WXS file test.wxs, event handling functions and functions triggered by property changes are defined and exported:
    Note:
    Currently, the events of native components and the bindinput events of <input> and <textarea> components are not supported.
    Currently, within the WXS function, only the console.log method is supported for logging to troubleshoot issues. Please note that consecutive duplicate logs will be filtered out.

    Refer to

    WXML offers two methods of file referencing: import and include.

    import

    import allows the use of the template defined in the target file, as follows:
    A template named item is defined in item.wxml:
    <!-- item.wxml -->
    <template name="item">
    <text>{{text}}</text>
    </template>
    Upon referencing item.wxml in index.wxml, the item template can be utilized:
    <import src="item.wxml" />
    <template is="item" data="{{text: 'forbar'}}" />

    Scope of import

    The concept of scope applies to import, meaning it only imports the template defined in the target file, and does not import the template that the target file imports.
    For instance: If C imports B, and B imports A, then C can utilize the 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

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

    Contact our sales team or business advisors to help your business.

    Technical Support

    Open a ticket if you're looking for further assistance. Our Ticket is 7x24 avaliable.

    7x24 Phone Support