View
The view layer of the framework is written in FXML and FTSS, and the basic unit is the component.
- FXML is used to describe the structure of a page, similar to HTML;
- FTSS is used to describe the style of components and pages, and is a subset of css; fts is a set of scripting languages for Mini App. The basic syntax is the same as javascript, combined with FXML, which can create the structure of the page.
Component is the basic unit of view, similar to various tags of HTML pages, such as div, span, img, etc
# 1. FXML
FXML is a set of tagging language designed by the framework. Combined with basic components and event system, the structure of the page can be constructed.
Here are some simple examples:
# 1.1 Data binding
<!--fxml-->
<view> hello {{name}} </view>
// page.js
Page({
data: {
name: 'cortana'
}
})
# 1.2 List rendering
<!--fxml-->
<view ft:for="{{array}}"> {{item}} </view>
// page.js
Page({
data: {
array: ["Apple", "banana", "orange", "watermelon"]
}
})
# 1.3 Conditional rendering
<!--fxml-->
<view ft:if="{{type == 1}}"> type 1 </view>
<view ft:elif="{{view == 2'}}"> type 2 </view>
<view ft:else="{{view == 3}}"> type 3 </view>
// page.js
Page({
data: {
type: 1
}
})
# 1.4 Templates
<!--fxml-->
<template name="cat">
<view>
age: {{name}}, age: {{age}}
</view>
</template>
<template is="cat" data="{{...cat1}}"></template>
// page.js
Page({
data: {
cat1: {name: 'blue', age: '2'},
}
})
# 1.5 Events
<view bindtap="getDate"> {{date}} </view> //Click event bindtap
Page({
data: {
date: ""
},
getDate: function(e) {
this.setData({
date: new Date()
})
}
})
# 2. FTSS
Features of the CSS FTSS extension are:
- Size unit
- Style import
# 2.1 size unit
Rpx (responsive pixel): Can be adaptive according to the screen width. The specified screen width is 750rpx. For example, on the iPhone 6, the screen width is 375px and there are 750 physical pixels, then 750rpx = 375px = 750 physical pixels, 1rpx = 0.5px = 1 physical pixel.
| equipment | Rpx to px (screen width/750) | PX conversion RPX (750/screen width) |
|---|---|---|
| iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
| iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
| iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
Attention
- Designers can use the iPhone 6 as a standard for visual scripts when developing the Neuxnet Mini App.
- There will inevitably be some glitches on smaller screens, try to avoid this when developing.
# 2.2 Style import
Use the @import statement to import an outreach style sheet. @import is followed by the relative path of the outreach style sheet that needs to be imported. Use; to indicate the end of the statement.
** sample code **
/** common.ftss **/
.small-p {
padding:5px;
}
/** app.ftss **/
@import "common.ftss";
.middle-p {
padding:15px;
}
# 2.3 internal connection styles
The use of style and class attributes to cgroup the style of the piece is supported on the framework component.
Style: Static styles are uniformly written into the class. Style receives dynamic styles and will be parsed at runtime. Please try to avoid writing static styles into style, so as not to affect the rendering speed.
<view style="color:{{color}};" />
Class: Used to specify a style rule, its attribute value is a collection of class selector names (style class names) in the style rule. The style class names do not need to be marked with., and the style class names are separated by spaces.
<view class="normal_view" />
# 2.4 selectors
Currently supported selectors are:
| Selector | Sample | Sample description |
|---|---|---|
| .class | .intro | Choose all components with class = "intro" |
| #id | #firstname | Choose a component with ID = "firstName" |
| element | view | Select all view components |
| element, element | View, checkbox Select all document view components and all checkbox components | |
| ::after | view::after | Insert the content after the view component |
| ::before | view::before | Insert content in front of the view component |
# 2.5 Global styles and local styles
Styles defined in app.ftss are global styles that apply to each page. Styles defined in page’s FTSS file are local styles that only apply to the corresponding page and override the same selectors in the app.ftss.
# 3. FTS
FTS (is a set of scripting languages for Mini App, combined with FXML, you can build the structure of the page.
Attention
FTS does not depend on the base library version of the SDK and can run in all versions of Mini App. FTS and JavaScript are different languages and have their own syntax, which is not consistent with JavaScript. The running environment of FTS is isolated from other JavaScript code. FTS cannot call functions defined in other JavaScript files, nor can it call APIs provided by Mini App. FTS functions cannot be used as event callbacks for components.
Here are some simple examples of using FTS:
** page rendering **
<!--fxml-->
<fts module="m1">
var msg = "hello world";
module.exports.message = msg;
</fts>
<view> {{m1.message}} </view>
** page output **
hello world
** Data Processing **
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5, 1, 2, 3, 4]
}
})
<!--fxml-->
<!-- The getMax function below accepts an array and returns the value of the largest element in the array -->
<fts module="m1">
var getMax = function(array) {
var max = undefined;
for (var i = 0; i < array.length; ++i) {
max = max === undefined ?
array[i] :
(max >= array[i] ? max : array[i]);
}
return max;
}
module.exports.getMax = getMax;
</fts>
<!-- Call the getmax function in FTS, and the parameter is the array in page.js -->
<view> {{m1.getMax(array)}} </view>
** page output **
5
# 4. FTS response event
# 4.1 Background
When the Mini App needs to achieve the effect of frequent user interaction, if the conventional implementation method is adopted, such as:
The page has 2 elements A and B. The user makes a touchmove gesture on A and asks B to follow the move. Mobile-view is a typical example. The response process of a touchmove event is:
I. The touchmove event is thrown from the view layer (View) to the logical layer (Service)
Ii. The logical layer (Service) handles the touchmove event, and then changes the position of B through setData
The response of a touchmove needs to go through two communication between the logic layer and the rendering layer and one rendering, and the communication time is relatively large.
In addition, setData rendering will also block the execution of other scripts, resulting in a delay in the animation process of the entire user interaction, and the actual performance of the interaction will not be ideal.
# 4.2 Solutions
For the above reasons, you can use the FTS function to respond to Mini App events, and then process the dom style at the View layer to achieve better results.
Currently, it can only respond to events of built-in components, and custom component events are not supported.
In addition to pure logical operations, the FTS function can also access and set the class and style of the component through the encapsulated ComponentDescriptor instance. For interactive animation, setting style and class can meet most needs.
An example of an FTS function is as follows:
var event = function(event, ownerInstance) {
// Gets the component instance
var instance = ownerInstance.selectComponent('.some-component')
instance.setStyle({
color: 'red',
"font-size": '18rpx'
})
instance.setClass('other-class')
return false // does not bubble up
}
The imported parameter event is a ComponentDescriptor instance with more event.instance on the basis of the Mini App event object to represent the component that triggered the event.
ownerInstance represents the ComponentDescriptor instance of the component where the component that triggered the event is located. If the component that triggered the event is within the page, ownerInstance represents the page instance.
The APIs currently supported by ComponentDescriptor are as follows:
| method | parameter | Description |
|---|---|---|
| selectComponent | selector Object | Returns the ComponentDescriptor instance of the component. |
| selectAllComponents | Selector object array | Returns an array of ComponentDescriptor instances for the component. |
| setStyle | Object/string | Set the component style, support rpx. The style priority set is higher than the style defined in the component fxml. The style of the topmost page cannot be set. |
| addClass/removeClass/hasClass | string | Set the class of the component. The class priority set is higher than the class defined in the component fxml. The class of the topmost page cannot be set. |
| callMethod | (funcName:string, args:object) | Call the function defined by the current component/page at the logical layer (App Service). funcName represents the function name, and args represents the parameters of the function. |
| getComputedStyle | Array <string> | Specifies a list of style names, and returns the current value of the style name corresponding to the node. |
| getBoundingClientRect | None | Returns size information for the node. |
# 4.3 How to use
FXML defines events:
<fts module="event" src="./event.fts"></fts>
<view bindtouchmove="{{event.touchmove}}" class="movable"></view>
Note: FTS functions must be enclosed in {{}}.
event.ftx file defines and exports functions:
module.exports = {
touchmove: function(event, instance) {
console.log('log event')
},
otherEvent: function(event, instance) {
console.log('log event')
}
}
# 5. Simple two-way binding
In FXML, normal attribute binding is one-way. E.g:
<input value="{{value}}" />
If you use this.setData ({value: ‘leaf’}) to update the value, the value displayed in both the this.data.value and the text box will be updated to leaf; however, if the user modifies the value in the text box, it will not change the this.data.value at the same time.
If you need to change the this.data.value at the same time as user input, you need to use a simple two-way binding mechanism. In this case, you can add the model: prefix before the corresponding item:
<input model:value="{{value}}" />
In this way, if the value of the text box is changed, the this.data.value will also change at the same time. At the same time, all the positions bound to the value in the FXML will also be updated together, and the data listener will also be triggered normally.
Preview effects in developer tools
Expressions used for bidirectional binding have the following restrictions:
<input model:value="The value is {{value}}" />
<input model:value="{{ a + b }}" />
Are illegal;
<input model:value="{{ a.b }}" />
Such expressions are not currently supported.
# 5.1 Pass bidirectional binding in custom component
Two-way binding can also be used on custom components. The following custom components:
// custom-component.js
Component({
properties: {
myValue: String
}
})
<!-- custom-component.FXML -->
<input model:value="{{myValue}}" />
This custom component binds its own myValue property bidirectionally to the value property of the text box in the component. Thus, if the page uses this component like this:
<custom-component model:my-value="{{pageValue}}" />
When the value of the text box changes, the myValue property of the custom component will change at the same time, so that the this.data.pageValue of the page will also change at the same time, and all the positions bound to pageValue in the FXML of the page will also be updated.
# 5.2 Trigger a two-way binding update in a custom component
Custom components can also trigger two-way binding updates themselves by using setData to set their own properties. E.g:
// custom-component.js
Component({
properties: {
myValue: String
},
methods: {
update: function() {
// Update myValue
this.setData({
myValue: 'leaf'
})
}
}
})
If the page uses this component like this:
<custom-component model:my-value="{{pageValue}}" />
When the component uses setData to update myValue, the this.data.pageValue of the page changes at the same time, and all positions in the page FXML that bind pageValue are also updated.
# 6. Basic components
The framework provides developers with a series of basic components that developers can combine for rapid development. For details, please refer to the component documentation.
# 6.1 What is a component
- Components are the basic building blocks of the view layer.
- A component usually includes a start tag and an end tag attributes, which are used to decorate the component’s content within the two tags.
<tagname property="value">
Content goes here ...
</tagname>
Attention
All components and properties are lowercase, hyphen-concatenated
attribute type **
| Type | Description | Annotation |
|---|---|---|
| Boolean | Boolean value | The component writes the property, and no matter what the value is, it is treated as true; the property value is false only if there is no such property on the component. If the property value is a variable, the value of the variable will be converted to Boolean type |
| Number | Number | 1, 2.5 |
| String | The string | “string” |
| Array | Array | [ 1, “string” ] |
| Object | Object | { key: value } |
| EventHandler | The event handler name "handlerName" is the event handler name defined in page | |
| Any | Any attribute |
** public attribute **
All components have the following properties
| Property Name | Type | Description | Annotation |
|---|---|---|---|
| id | String | The unique label for the component | Keep the entire page unique |
| class | String | The component's style class | Style class defined in the corresponding FTSS |
| style | String | The inline style of the component | Dynamically settable internal connection styles |
| hidden | Boolean | Whether the component displays | All components are displayed by default |
| data-* | Any | Custom properties | When an event is fired on a component, it is sent to the event handler |
| bind* / catch* | EventHandler | Events for components See Events |
** special attribute **
Almost all components have their own custom properties, you can modify the function or style of the component, please refer to the definition of each component.
# 7. Get node information on the interface
# 7.1 FXML node information
The node information query API can be used to obtain information such as node properties, styles, and positions on the interface.
The most common usage is to use this interface to query the current position of a node, as well as the scrolling position of the interface.
** sample code **
const query = ft.createSelectorQuery()
query.select('#the-id').boundingClientRect(function(res){
res.top // the upper boundary coordinates of the // #the-id node (relative to the display area)
})
query.selectViewport().scrollOffset(function(res){
res.scrollTop // The vertical scroll position of the display area
})
query.exec()
In the above example, #the-id is a node selector, which is similar to but slightly different from the CSS selector, see the description of the SelectorQuery.select.
In custom components or pages that contain custom components, it is recommended to use this.createSelectorQuery instead of ft.createSelectorQuery, which ensures that nodes are selected in the correct range.
# 7.2 FXML node layout intersection state
The Node Layout Intersection State API can be used to listen to the intersection state of two or more component nodes at layout positions. This set of APIs can often be used to infer whether and what percentage of certain nodes can be seen by the user.
The main concepts covered by this set of APIs are as follows.
- Reference node: The listening reference node takes its layout area as the reference area. If there are multiple reference nodes, the intersection of their layout areas will be taken as the reference area. The page display area can also be used as one of the reference areas.
- Target node: The target of monitoring, which can only be one node by default (when using the selectAll option, multiple nodes can be monitored at the same time).
- Intersection area: The intersection area of the layout area of the target node and the reference area.
- Intersection ratio: The proportion of the intersecting area to the reference area.
- Threshold: Intersection ratio If a threshold is reached, the listener’s callback function is triggered. Thresholds can be multiple. The following sample code can trigger a callback function every time the target node (specified with selector .target-class) enters or leaves the page display area.
** sample code **
Page({
onLoad: function(){
ft.createIntersectionObserver().relativeToViewport().observe('.target-class', (res) => {
res.id // Target node ID
res.dataset // target node dataset The proportion of the res.intersection AreaRatio // intersection area to the layout area of the target node
res.intersectionRect // intersecting areas
Res.intersectionRect.left // The left boundary coordinate of the intersecting area
Res.intersectionRect.top // the upper boundary coordinates of the // intersecting area
res.intersectionRect.width // The width of the intersecting area
res.intersectionRect.height // The height of the intersecting area
})
}
})
The following sample code can intersect or separate the target node (specified with selector .target-class) and the reference node (specified with selector .relative-class) within the page display area, and the degree of intersection or separation reaches the target node layout area 20% and 50% of the time, the callback function is triggered.
** sample code **
Page({
onLoad: function(){
ft.createIntersectionObserver(this, {
thresholds: [0.2, 0.5]
}).relativeTo('.relative-class').relativeToViewport().observe('.target-class', (res) => {
res.intersectionRatio //The proportion of the res.intersection AreaRatio // intersection area to the layout area of the target node
res.intersectionRect // intersecting areas
Res.intersectionRect.left // The left boundary coordinate of the intersecting area
Res.intersectionRect.top // the upper boundary coordinates of the // intersecting area
res.intersectionRect.width // The width of the intersecting area
res.intersectionRect.height // The height of the intersecting area
})
}
})
Attention
The intersection area with the page display area does not accurately represent the area visible to the user, because the area involved in the calculation is the “layout area”, and the layout area may be cropped and hidden by other nodes when drawing (in the case of the ancestor node with the overflow style hidden). node) or masking (in the case of fixed nodes).
In custom components or pages that contain custom components, it is recommended to use this.createIntersectionObserver instead of ft.createIntersectionObserver, which ensures that nodes are selected in the correct range.
# 8. Response to display area changes
# 8.1 Display area size
The display area refers to the area that can be freely displayed in the Mini App interface. By default, the size of the Mini App display area does not change since the page is initialized. But the following two ways can change this default behavior.
# 8.1.1 Enable screen rotation support on your phone
Starting from version 1.5.33 of the Mini App Basic Library, the Mini App supports screen rotation on mobile phones. The way to make the page in the Mini App support screen rotation is to set “pageOrientation”: “auto” in the window section of the app.json, or configure “pageOrientation”: “auto” in the page json file.
The following is an example of enabling screen rotation in a single page json file.
** code example **
{
"pageOrientation": "auto"
}
If the above statement is added to the page, the page will rotate as the screen rotates, and the display area size will change as the screen rotates.
Starting from MiniApp base library version 1.5.33, pageOrientation can also be set to landscape, which means fixed to landscape display.
# 8.1.2 Enable screen rotation support on iPad
Starting from version 1.5.33 of the Mini App Basic Library, Mini App running on iPad can support screen rotation. The way to make Mini App support iPad screen rotation is to add “resizable”: true to the app.json.
** code example **
{
"resizable": true
}
If the Mini App adds the above statement, the Mini App will rotate as the screen rotates, and the display area size will change as the screen rotates.
Attention
You cannot individually configure whether a page supports screen rotation on iPad.
# 8.2 Media Query
Sometimes, the layout of the page will vary for display areas of different sizes. At this point, media query can be used to solve most problems.
** code example **
.my-class {
width: 40px;
}
@media (min-width: 480px) {
/* Style rules that only take effect on screens at 480px or wider */
.my-class {
width: 200px;
}
}
# 8.3 Screen rotation events
Sometimes, using media query alone cannot control some subtle layout changes. At this point you can use js as a helper.
To read the display area size of the page in js, you can use selectorQuery.selectViewport.
The event that the page size changes, you can use the onResize of the page to listen. For custom components, you can use the resize lifecycle to listen. The size information of the display area will be returned in the callback function. (Supported since base library version 1.5.33.)
** code example **
Page({
onResize(res) {
res.size.windowWidth // New display area width
res.size.windowHeight // New display area height
}
})
# 9. Page routing
The routing of all pages in the Mini App is all managed by the Mini App framework.
# 9.1 page stack
The framework maintains all current pages in the form of stacks. When a route switch occurs, the page stack behaves as follows:
| Routing mode | Page stack performance |
|---|---|
| Initialize the | New page stack |
| Open a new page | New page stack |
| Page redirect | The current page is out of the stack, and a new page is in the stack |
| Page back to | The page keeps popping until the target returns to the page |
| Tab | Switch, all pages are out of the stack, leaving only the new Tab page |
| Reload | All pages are out of the stack, leaving only new pages |
getCurrentPages()
The getCurrentPages () function is used to obtain an instance of the current page stack, which is given in the order of the stack in the form of an array, the first element is the home page, and the last element is the current page.
Attention
- Do not attempt to manually modify the page stack, which will result in wrong routing and page state.
- Do not call getCurrentPages () when App.onLaunch, the page has not yet been generated.
Routing method **
The triggering method for the route and the page life cycle function are as follows:
| Routing mode | Trigger timing | The page before routing | The page | after routing |
|---|---|---|---|---|
| Initialize the | The first page opened by Mini App | onLoad, onShow | ||
| Open a new page | Call API ft.navigateTo or use component \<navigator open-type="navigateTo"/> | onHide | onLoad, onShow | |
| Page redirect | Call API ft.redirectTo or use component \<navigator open-type="redirectTo"/> | onUnload | onLoad, onShow | |
| Page back to | Call the API ft.navigateBack or use the component \<navigator open-type="navigateBack"> or the user presses the upper left back button | onUnload | onShow | |
| Tab | Switch, call API ft.switchTab or use component \<navigator open-type="switchTab"/> or user switch tab | For various situations, please refer to the table below | ||
| Restart the | Call API ft.reLaunch or use component \<navigator open-type="reLaunch"/> | onUnload | onLoad, onShow |
The corresponding life cycle of Tab switching (take A and B pages as Tabbar pages, C is the page opened from A page, and D page is the page opened from C page as an example):
| The current page is | The page | after routing Triggered Lifecycle (in order) |
|---|---|---|
| A | A | Nothing happend |
| A | B | A.onHide(), B.onLoad(), B.onShow() |
| A | B (Open Again) | A.onHide(), B.onShow() |
| C | A | C.onUnload(), A.onShow() |
| C | B | C.onUnload(), B.onLoad(), B.onShow() |
| D | B | D.onUnload(), C.onUnload(), B.onLoad(), B.onShow() |
| D (From Forwarding) | A | D.onUnload(), A.onLoad(), A.onShow() |
| D (From Forwarding) | B | D.onUnload(), B.onLoad(), B.onShow() |
Tip
- navigateTo, redirectTo can only open non-tabBar pages.
- switchTab can only open tabBar pages.
- reLaunch can open any page.
- The tabBar at the bottom of the page is determined by the page, that is, as long as it is a page defined as tabBar, there is a tabBar at the bottom.
- The parameters for calling the page routing belt can be obtained in the onLoad of the target page.
# 10. Animation
# 10.1 Common ways of interface animation
In Mini Apps, you can often use CSS gradual changes and CSS animations to create simple interface animations.
Preview effects in developer tools
During animation, you can use bindtransitionend bindanimationstart bindanimationiteration bindanimationend to listen for animation events.
| Event Name | Meaning |
|---|---|
| transitionend | CSS gradual change ends or wx.createAnimation ends a phase |
| animationstart | CSS animation starts |
| animationiteration | CSS animation ends a stage |
| animationend | CSS animation ends |
Note: These events are not bubbling events and need to be bound to the node where the animation actually occurred to take effect.
At the same time, you can also use the wx.createAnimation interface to dynamically create simple animation effects. (The following keyframe animation interface is recommended in the new version of the Mini App basic library instead.)
# 10.2 Keyframe animation
There is also a friendlier way of creating animations to replace the old wx.createAnimation. It has better performance and a more controllable interface.
In a page or custom component, when keyframe animation is required, you can use this.animate interface:
this.animate(selector, keyframes, duration, callback)
Parameter description
| Properties | Type | The default value is | Required | Description |
|---|---|---|---|---|
| selector | String | Yes | Selector (same SelectorQuery.select selector format) | |
| keyframes | Array | Yes | Key frame information | |
| duration | Number | Yes | Animation duration in milliseconds | |
| callback | function | No | Callback function after animation is complete |
Structure of objects in keyframes
| Properties | Type | The default value is | Required | Description |
|---|---|---|---|---|
| offset | Number | No | The offset of the keyframe, the range [0-1] | |
| ease | String | linear | No | Animation easing function |
| transformOrigin | String | No | The base point location, which is the CSS transform-origin | |
| backgroundColor | String | No | Background color, i.e.CSS background-color | |
| bottom | Number/String | No | The bottom edge position, the CSS bottom | |
| height | Number/String | No | Height, i.e.CSS height | |
| left | Number/String | No | The left position, that is, CSS left | |
| width | Number/String | No | Width, i.e.CSS width | |
| opacity | Number | No | Opacity, or CSS opacity | |
| right | Number | No | Right position, i.e.CSS right | |
| top | Number/String | No | The top edge position, the CSS top | |
| matrix | Array | No | Transformation matrix, i.e.CSS transform matrix | |
| matrix3d | Array | No | The three-dimensional transformation matrix, or CSS transform matrix3d | |
| rotate | Number | No | Rotate, i.e.CSS transform rotate | |
| rotate3d | Array | No | 3D rotation, i.e.CSS transform rotate3d | |
| rotateX | Number | No | X direction rotation, that is, CSS transform rotateX | |
| rotateY | Number | No | Rotate in the Y direction, that is, CSS transform rotateY | |
| rotateZ | Number | No | Z direction rotation, that is, CSS transform rotateZ | |
| scale | Array | No | Scaling, i.e.CSS transform scaling | |
| scale3d | Array | No | 3D scaling, i.e.CSS transform scale3d | |
| scaleX | Number | No | X-direction scaling, i.e.CSS transform scaleX | |
| scaleY | Number | No | Y direction scaling, that is, CSS transform scaleY | |
| scaleZ | Number | No | Z-direction scaling, i.e.CSS transform scaleZ | |
| skew | Array | No | Tilt, i.e.CSS transform skew | |
| skewX | Number | No | X direction tilt, i.e.CSS transform skewX | |
| skewY | Number | No | The Y direction is tilted, that is, the CSS transform skewY | |
| translate | Array | No | Displacement, i.e.CSS transform translate | |
| translate3d | Array | No | 3D displacement, i.e.CSS transform translate3d | |
| translateX | Number | No | X direction displacement, i.e.CSS transform translateX | |
| translateY | Number | No | Y direction displacement, that is, CSS transform translateY | |
| translateZ | Number | No | Z direction displacement, i.e.CSS transform translateZ |
# [#] (#示例代码) sample code
this.animate('#container', [
{ opacity: 1.0, rotate: 0, backgroundColor: '#FF0000' },
{ opacity: 0.5, rotate: 45, backgroundColor: '#00FF00'},
{ opacity: 0.0, rotate: 90, backgroundColor: '#FF0000' },
], 5000, function () {
this.clearAnimation('#container', { opacity: true, rotate: true }, function () {
console .log("cleared the opacity and root attributes on #container")
})
}.bind(this))
this.animate('.block', [
{ scale: [1, 1], rotate: 0, ease: 'ease-out' },
{ scale: [1.5, 1.5], rotate: 45, ease: 'ease-in', offset: 0.9},
{ scale: [2, 2], rotate: 90 },
], 5000, function () {
this.clearAnimation('.block', function () {
console.log("Cleared all animation properties on .block")
})
}.bind(this))
After calling the animate API, some style properties will be added to the node to overwrite the original corresponding styles. If you need to clear these styles, you can use this.clearAnimation to clear these properties after all the animations on the node are executed.
this.clearAnimation(selector, options, callback)
Parameter description
| Properties | Type | The default value is | Required | Description |
|---|---|---|---|---|
| selector | String | Yes | Selector (same SelectorQuery.select selector format) | |
| options | Object | No | Attributes that need to be cleared, if not filled in, all will be cleared | |
| callback | Function | No | Clear the callback function after completion |
# 10.3 Advanced animation methods
In some complex scenes, the above animation method may not be applicable.
The way WXS responds to events can be dynamically adjusted by using WXS to respond to events. Animation effects can be achieved by constantly changing the value of the style attribute. At the same time, this method can also dynamically generate animations according to the user’s touch events.
Continuous use of setData to change the interface can also achieve the effect of animation. This can change the interface arbitrarily, but usually produces large delays or cards, and even causes the Mini App to freeze. At this point, you can improve performance by changing the setData of the page to setData in the custom component.
# 11. Initial render cache
# 11.1 How the initial render cache works
The initialization of the Mini App page is divided into two parts.
- Logic layer initialization: Load the required Mini App code, initialize the page this object (including the this object of all custom components it involves), and send relevant data to the view layer.
- View layer initialization: Load the necessary Mini App code, then wait for the logic layer to initialize and receive the data sent by the logic layer, and finally render the page.
When starting the page, especially when the Mini App cold starts and enters the first page, the logic layer takes a long time to initialize. During page initialization, the user will see the standard loading screen of the Mini App (during a cold start) or may see a slight white screen (during a page jump).
Enabling the initial rendering cache allows the view layer to directly display the rendering results of the initial data of the page to the user in advance without waiting for the logic layer to be initialized, which can greatly advance the time when the page is visible to the user. It works as follows:
- After the Mini App page is opened for the first time, record the initial data rendering result of the page and write it into a persistent cache area (the cache can be retained for a long time, but it may be due to Mini App updates, basic library updates, storage space recovery, etc. reason is cleared);
- When the page is opened for the second time, check whether the rendering result of the initial data of the page is still stored in the cache, and if so, display the rendering result directly;
- If the rendered results in the cache are displayed, the page cannot respond to user events for the time being, and cannot respond to user events until the logic layer is initialized.
With the initial render cache, you can:
- Quickly display parts of the page that never change, such as the navigation bar;
- Pre-display a skeleton page to improve user experience;
- Display custom loading prompts;
# 11.2 Supported components
During the initial render cache phase, complex components cannot be displayed or respond to interactions.
Currently supported built-in components:
<view /><text /><button /><image /><scroll-view />- Custom components themselves can be displayed (but the built-in components used in them also follow the above restrictions).
# 11.3 Static initial render cache
The easiest way to enable initial render caching is to add the configuration item "initialRenderingCache": "static" to the page’s json file:
{
"initialRenderingCache": "static"
}
If you want to enable it for all pages, you can add this configuration in the window configuration section of app.json:
{
"window": {
"initialRenderingCache": "static"
}
}
After adding this configuration item, preview the Mini App homepage in the phone, then kill the Mini App to enter again, and the homepage will be rendered through the initial rendering cache.
Please note
In this case, the initial render cache records the result of page data applied to page FXML, without any setData result.
For example, if you want to display the words “loading” in the page, these words are controlled by the loading data field:
<view wx:if="{{loading}}" > is loading</view>
In this case, loading should be specified as true in data, as in:
// The right thing to do
Page({
data: {
loading: true
}
})
Instead of loading setting true with setData:
// Wrong approach! Don't do it!
Page({
data: {},
onLoad: function() {
this.setData({
loading: true
})
}
})
In other words, this practice only includes the rendering result of the page data, which is the purely static component of the page.
# 11.4 Add dynamic content to the initial render cache
In some scenarios, only the rendering result of the page data will be limited. Sometimes you want to show some variable content, such as the URL of the displayed advertising image.
A “dynamic” initial render cache can be used in this case. First, configure "initialRenderingCache": "dynamic":
{
"initialRenderingCache": "dynamic"
}
At this point, the initial render cache will not be automatically enabled, and you need to call this.setInitialRenderingCache(dynamicData) in the page to enable it. Among them, dynamicData is a set of data that participates in page FXML rendering together with data.
Page({
data: {
loading: true
},
onReady: function() {
this.setInitialRenderingCache({
loadingHint: 'Loading' // This part of the data will be applied to the interface, which is equivalent to an additional setData on top of the initial data
})
}
})
<view wx:if="{{loading}}">{{loadingHint}}</view>
In principle, in the way of dynamically generating the initial rendering cache, the page will be re-rendered once in the background using dynamic data, so the overhead is relatively large. Therefore, try to avoid frequent calls to this.setInitialRenderingCache. If it is called multiple times within a page, only the last call will take effect.
Note:
- The call timing cannot be earlier than
onReadyofPageorComponentofreadylifetime, otherwise there may be a negative impact on performance. - If you want to disable the initial render cache, call
this.setInitialRenderingCache(null).