Author introduction: He Yanxi, meituan Dianping engineer, 4 years of Web development experience, is now a member of meituan Dianping ordering team.
In this issue, I would like to share with you some of the development experience of the View View layer in the public Dianping ordering applet. Some examples in this paper come from the menu page of the small program “Dianping order food”.
The page code structure is as follows:
Menu ├── Menu.html ├─ menu.js ├─ menu. Json ├─ menu
The View View layer of the small program we are going to say is composed of WXML(menu.html) and WXSS(menu.less), which is displayed by the smallest unit of View – component. The view layer reflects the data of the logical layer (menu.js+menu.json) into a view, and sends the events defined in the view layer to the logical layer, as shown in a diagram.
WXML
WXML (WeiXin Markup Language) corresponds to HTML and is used to describe the structure of a page. It is similar to JSX of React. Menu. HTML is a WXML syntax, and the top layer of a page is the page node. After capturing the data defined by the logical layer in WXML, you present the data through your own set of syntax and logic. Structurally the component is its smallest unit and is rendered dynamically in the following way.
1. Data binding
Data binding is the simplest way to use data, with Mustache’s variable substitution syntax, wrapping variables in double curly braces, and placing the data in quotes if the component’s attributes.
<view class="dish-item" data-id="{{dishId}}"><text class="name">{{dishName}}</text></view>Copy the code
Data binding also supports the ES6 specification’s extended operator “…” Destruct assignment.
<template is="dishItem" data="{{... item, count, soldout: true }}"></template>Copy the code
2. Logical operation
Operations such as arithmetic operation, ternary operation, logical judgment and string concatenation can be performed in double curly braces.
<text class="{{orderBanner.type ! = = 0? 'order-banner arrow' : 'order-banner'}}">{{orderBanner.text}}</text>Copy the code
3. Conditional rendering
Instead of writing the render content in the if/else condition in the common template language, the conditional rendering of the applet writes the render condition directly in the wx:if/wx:else attribute of the render content component. If the render component is multiple, multiple components can be placed in the component. The render condition is placed in the wx:if/wx:else property of the
component, which acts as a container and does not render in the page.
if/else
<text wx:if="{{item.soldOut}}" class="status-soldout"> </text> <template wx:else is="numberCount" data="{{count: cartSpuCount[item.spuId]}}"></template>Copy the code
<block>
<block wx:if="{{serverError}}"> <text> <button class="menu-btn" bindtap="requestMenu"> </button> </block>Copy the code
4. List rendering
List rendering is the wX :for attribute value of a traversal element as a render component, with the following attributes associated with it:
- Wx :key: unique identifier of traversal elements. It is mainly used to update dom when data changes dynamically and can be ignored if data does not change
- Wx :for-item: the variable name of the traversal element. The default item
- Wx :for-index: variable name traversing element subscript, default index Note: although the above attribute values are strings, do not use – between words for correct values (for example, when used dish-item {{dish-item}} will be parsed into a minus sign and cannot get the value).
The data in the project is relatively complex, and the test data is used for example:
<block wx:for="{{testData}}"
wx:for-item="mainitem"
wx:key="{{mainindex}}"
wx:for-index="mainindex">
<view wx:for="{{mainitem}}"
wx:for-item="subitem"
wx:key="{{subitem.id}}"
wx:for-index="subindex">
<view class="dom-item">Index: {{mainIndex}} id: {{subitem.id}} name: {{subitem.</view>
</view>
</block>Copy the code
The above code structure is divided into two layers: 1. The first layer block loop through the testData array, each traversal value variable named mainItem; 2, layer 2 view loop through the mainItem array, each traversal value variable named subitem, display layer 1 index, layer 2 ID and name attributes;
// Create a page instance object
Page({
/** * initial data for the page */
data: {
"testData": [[{"id": "1-1"."name": "Node 1-1"
}, {
"id": "1-2"."name": "Nodes 1-2"
}], [{
"id": "2-1"."name": "Node 2-1"
}, {
"id": "2-2"."name": "Nodes 2-2"}}}]])Copy the code
Show results:
I ran into it during development
- Wx :for In layer 2, wx:for-item and wx:for-index are invalid
- Wx: For render exception
- Wx :for wx:index error in the above small program update version have been fixed.
Note:
- 1. Loop traversal. In addition to the specified array types, wx:for can also be used for property traversal for object types, where for-index is the key value of the property.
Replace testData with an object type in the above example:
// Create a page instance object
Page({
/** * initial data for the page */
data: {
"testData": {
"a": [{
"id": "1-1"."name": "Node 1-1"
}, {
"id": "1-2"."name": "Nodes 1-2"}]."b": [{
"id": "2-1"."name": "Node 2-1"
}, {
"id": "2-2"."name": "Nodes 2-2"}}}}])Copy the code
The result is:
- 2, loop duration, small program before also support WX: Forin traversal, function and WX :for similar, but the official document did not explain, now try not to report an error, but the function has failed, estimated later has been merged.
5. Templates & References
Templates are similar to the component concept in React. You can define code snippet in the template and then call it in different places to reduce duplicate code.
1. Definition: Use the name attribute as the name of the template, and then define the template code snippet within
; 2. There are two ways of use:
-
- Import the defined file through import, and then declare the required template using the is attribute of the
component, and then pass in the data required by the template. The template has its own scope, and can only use the data passed in by data.
Note:
- Only the
defined in the object file is imported, and the
referenced in the object file is not referenced. - The React parent component passes data to its props to its child components by reference. The child components can modify their props to affect the data of the parent component. Applets’ templates can only use incoming data in one direction.
Example (single dish component) :
<import src=".. /.. /components/common/dish-item.wxml" />
<template is="dishItem" data="{{... item}}"></template>Copy the code
6. Bind events
The event name is a string and the event parameter is passed by default. Other parameters cannot be customized. Therefore, the required parameters are generally bound to the component through the data-attribute and obtained from e.currenttarget. dataset.
<view class="cart-btn" data-type="1" bindtap="redirectCart"> < span style = "box-sizing: border-box! Important;/view>Copy the code
WXSS
WeiXin Style Sheet (WXSS) corresponds to the CSS and describes the Style of a page. The styles defined in app.less are global and apply to each page; The styles defined in the WXSS file for page are local, apply only to the corresponding page, and override the same selectors in app.less, such as menu.less applied to menu.html in the code structure.
1. Supported features
- Inline styles: The component’s style receives dynamic styles, which are parsed at runtime. Try to avoid writing static styles into the style, which may affect rendering speed.
- Selectors For common selectors, the following selectors are supported:
Note: The green background color line indicates a selector that is not specified in the official documentation, but is also supported after personal testing.
Currently unsupported selectors are:
- As mentioned earlier, the top layer of the page is the node, so use the Page selector to style the entire page or modify the top layer node style.
- Applets currently do not support Media Query.
2. Extended features
- Size unit RPX RPX is a unit created by the small program and can be adjusted according to the screen width. Specify a screen width of 750rpx. For example, on iPhone6, the screen width is 375px and there are 750 physical pixels, then 750rpx = 375px = 750 physical pixels and 1rpx = 0.5px = 1 physical pixel.
Suggestion: Designers can use iPhone6 as the standard for visual draft when developing wechat mini programs.
Note: This unit should be avoided for accurate and small views because of the rounding effect that occurs when rendering with a small value, which can cause a large gap on smaller screens.
As shown in the figure below, the dish’s minus operation icon is 2px under the height of iPhone6 (750), directly rendered as 1px under iPhone4s (640) (the actual proportion value is 1.7px), and the plus button icon is 11px under the height of iPhone6 (750). On iPhone4s (640), the rendering is 9px(the actual scale is 9.48px), the error scale is small and there are no obvious visual problems, so the two will look incongruously.
- Style imports use the @import statement to import an external style sheet. The @import statement is followed by the relative path of the external style sheet to be imported. Indicates the end of the statement.
component
As mentioned in WXML, components are the basic building blocks of the view layer, similar to tags in HMTL. Based on the Web Component standard, attributes and content are used in the same way as HTML tags. Components and attributes must be lowercase.
1. Component list
2. Native components
According to the above statistics, input, Textarea, video, Map, and Canvas are native components of the system. Native components have relatively improved performance and user interaction.
Take the problem that the keyboard is blocked when the input element fixed is aroused in some models for example, the input box of the parent element Fixed on the H5 page of a Meizu model will be blocked:
In the same model applet, the input box will not be blocked:
3. Component properties
Support types
- Boolean: Indicates a Boolean value
- Number: digital
- String: character
- Array: an Array of
- Object: the Object
- EventHandler: EventHandler name, event binding (such as bindtap) property
- Any: Any attribute (not sure what it means)
The common property
- Id: unique identifier of a component
- Class: The component’s style class, corresponding to the class selector defined in WXSS
- Style: inline style
- Hidden: Whether the component is displayed
- Data -* : user-defined attribute, which can be passed to the customized data and obtained from the e. currenttarget. dataset event handler in the logical layer.
- Bind/catch: both are event bindings. The bind event binding does not prevent bubbling events from bubbling up. The catch event binding prevents bubbling events from bubbling up.
Special attributes Special attributes are defined by each component, for example, the size attribute of the
component. For details, see the official documentation for each component.
compatibility
Render mechanism according to the official documentation:
- On iOS, small program javascript code is running in JavaScriptCore, is rendered by WKWebView, the environment is iOS8, iOS9, iOS10;
- On Android, the javascript code of the applet is parsed by X5 JSCore, which is rendered by X5 based on the Mobile Chrome 37 kernel.
- In development tools, the javascript code of the applet runs in NWJS and is rendered by the Chrome Webview.
Due to the kernel rendering performance is inconsistent, H5 development process X5 browser and all types of models or system compatibility of some problems still exist in the small program.
FAQ Classification
- X5 Caniuse Tests
- Compatibility problems caused by iOS and Android versions: Small programs in iOS and Android require only the wechat version >= 6.5.3.
- Compatibility problems caused by fragmentation of Android models
Performance optimization
There are two common front-end template schemes:
- 1. Compile the template into JS function code and generate rendered DOM nodes through string stitching, such as Mustache/TPL (comment on internal development use). DOM nodes are all updated when data changes;
- 2. Besides stitching and rendering strings parse and compile, it has its own DOM node update mechanism, such as ue. Js/React, etc., and DOM Diff algorithm is used to update DOM nodes when data changes.
Components with keys are corrected when data changes trigger layer re-rendering, and the framework ensures that they are reordered rather than recreated to ensure that the components remain in their own state and to improve the efficiency of list rendering.
We don’t know how applets render components, but we can only guess at some of the problems encountered during development. Combined with the explanation of wX :key for list rendering by small program, we can see that its template rendering belongs to the second type, and the rendering will be optimized according to key when data is updated. However, there was no interface or performance debugging tool for the applet, so we had to experiment with different solutions and compare rendering speeds. Take the menu page as an example, the number of merchant dishes is hundreds or thousands, and the effect comparison after optimization is still quite obvious.
Take the plan
- 1. Reduce the number of data nesting layers/reduce the number of component nesting layers: The menu page flattens the dish data into one layer, and makes reasonable use of key values; When designing the component structure, the simplified component structure is adopted to reduce the performance consumption caused by data traversal and component nesting depth during rendering.
- 2. Split the components with changed data and those with unchanged data to reduce the amount of component updates caused by data changes, for example, separate the add and subtract buttons from dish information.
- 3. Use dynamic loading and other methods to reduce the amount of first-screen rendering data and improve user experience.
The time of this article is February 24, 2017. The mentioned small program does not support properties or bugs encountered at this time. Please check for subsequent updates or fixesThe official documentation.
Reference: wechat applets developer documentation