Mini App Document Mini App Document
  • Start
  • Configuration
  • Framework
  • Custom Components
  • Basic ability
  • Configuration
  • Interface
  • FXML syntax
  • FXS syntax
API
Components
IDE
  • Developer
  • Operator
  • Start
  • Configuration
  • Framework
  • Custom Components
  • Basic ability
  • Configuration
  • Interface
  • FXML syntax
  • FXS syntax
API
Components
IDE
  • Developer
  • Operator
  • Start

    • MiniApp hosting environment
    • Mini App operation mechanism
    • MiniApp code structure
    • Mini App directory structure
  • Configuration

  • MiniApp Framework

  • Custom component
    • 1. Component templates and styles
      • 1.1 Component Templates
      • 1.2 Template data binding
      • 1.3 component FXML slot
      • 1.4 Component Styles
      • 1.5 Component style isolation
      • 1.6 External style classes
    • 2. Component constructor
      • 2.1 Construct the page using the Component constructor
      • 2.2 Intercomponential communication and events
      • 2.2.1 Inter-component communication
      • 2.2.2 Listen for events
      • 2.2.3 Trigger event
      • 2.2.4 Get the component instance
      • 2.3 Component Lifecycle
      • 2.3.1 Defines the lifecycle method
      • 2.4 behaviors
      • Used in 2.4.1 components
      • 2.4.2 Override and combine rules for fields with the same name
      • 2.5 Relationships Between Components
      • 2.5.1 Define and use relationships between components
      • 2.5.2 Associates a class of components
      • 2.5.3 relations defines the segment
      • 2.6 Data Listener
      • 2.6.1 uses a data listener
      • 2.6.2 Listen for field syntax
      • 2.7 Pure data fields
      • A pure data field in component data
      • Pure data fields in component properties
      • Use a data listener to listen for data-only fields
      • 2.8 Abstract nodes
      • Use abstract nodes in components
      • Use components that contain abstract nodes
      • The default component for abstract nodes
      • Precautions
      • 2.9 Custom Component Extensions
      • Effect after extension
      • Use extensions
      • Code Example
      • 2.10 Get updated performance statistics
  • Basic ability

  • Guide
2022-08-05
Directory

Custom component

# 1. Component templates and styles


Similar to pages, custom components have their own FXML templates and FTSS styles.

# 1.1 Component Templates

Component templates are written in the same way as page templates. The node tree generated by the component template combined with the component data is inserted into the reference location of the component.

A '' node can be provided in the component template <slot>to host the child nodes provided when the component reference is made.

Code Sample

note

The custom component referenced in the template and its corresponding node name need to be explicitly defined in the json file, otherwise it will be treated as a meaningless node. In addition, node names can also be declared as abstract nodes.

# 1.2 Template data binding

Similar to normal FXML templates, you can use data binding so that you can pass dynamic data to the properties of child components.

Code Sample

In the example above, the components' properties propA and propB receive the data passed by the page. The page can change the bound data fields through setData.

note

Such a data binding can only pass JSON-compatible data. Starting with base library version 2.0.9, you can also include functions in your data (but these functions cannot be called directly in FXML, but can only be passed to child components).

# 1.3 component FXML slot

The FXML of a component can contain slot nodes that host FXML structures provided by component consumers.

By default, there can be only one slot in a component's FXML. When multiple slots are required, they can be declared enabled in component js.

At this point, multiple slots can be used in the FXML of this component, distinguished by different names.

When used, use the slot attribute to insert nodes onto different slots.

# 1.4 Component Styles

The component corresponds to the style of the FTSS file and takes effect only for nodes within the component's FXML. When writing component styles, you need to be aware of the following:

  • Components and pages that reference components cannot use the id selector (#a), property selector ([a]), and tag name selector, use the class selector instead.
  • The use of descendant selectors (.a.b) in pages of components and referenced components can behave unexpectedly in some extreme cases, so avoid using them.
  • The child element selector (.a>.b) can only be used between the view component and its child nodes, and use for other components can cause unexpected situations.
  • Inheriting styles, such as font, color, is inherited from outside the component to within the component.
  • In addition to inheriting styles, styles in app.ftss, styles on the page where the component resides, are not valid for custom components (unless you change the component style isolation option).
  • #a { } /* cannot be used in components */
  • [a] { } /* */ cannot be used in components
  • button { } /* cannot be used in components */ -a > .b { } /* does not necessarily take effect unless .a is a view component node */ Otherwise, a component can specify the default style of the node in which it resides, using the :host selector.

Code Sample

# 1.5 Component style isolation

By default, the style of a custom component is affected only by the custom component FTSS. Except in the following two cases:

1.app.ftss or FTSS for a page uses tag name selectors (or some other special selectors) to specify styles directly, and these selectors affect the page and all components. Usually this is not recommended. 2. Specify the special style isolation option styleIsolation.

The styleIsolation option is supported from base library version 1.1.7. It supports the following values:

  • isolated means that style isolation is enabled, and styles specified using class will not affect each other inside and outside custom components (the default in general);
  • apply-shared indicates that the page FTSS style will affect the custom component, but the style specified in the custom component FTSS will not affect the page;
  • shared indicates that the page FTSS style will affect the custom component, and the custom component The style specified in FTSS will also affect the page and other custom components that have apply-shared or shared set. When using the latter two, it is important to note the interaction of styles between components.

If this Component constructor is used to construct the page, the default value is shared. In addition, the MiniApp Base Library version 1.1.7 and later supports the addGlobalClass option, which sets addGlobalClass: true in component options.

This option is equivalent to setting the styleIsolation: apply-shared option, but it will be invalidated when the styleIsolation option is set.

Code Sample

# 1.6 External style classes

base library 1.1.7 is supported, and the lower versions need to be compatible.

Sometimes, a component wants to accept a style class that is passed in from outside. You can now define several external style classes in the Component with the externalClasses definition segment.

This attribute can be used to implement a hover-class property similar to that of the view component: a page can provide a style class that gives view a hover-class that is written in the page itself rather than in the implementation of the view component.

note

When using both normal style classes and external style classes on the same node, the priority of both classes is undefined, so it is best to avoid this situation.

Code Sample

In this way, the consumer of the component can specify the class corresponding to this style class, just as with normal properties, multiple corresponding classes can be specified.

Code Sample

# 2. Component constructor


The Component constructor can be used to define components, and when the Component constructor is called, you can specify the component's properties, data, methods, and so on.

For more information on parameter meanings and usage, refer to the Component reference documentation.

# 2.1 Construct the page using the Component constructor

In fact, the pages of the MiniApp can also be considered custom components. Thus, pages can also be constructed using the Component constructor, with the same definition segment and instance methods as normal components. However, at this point, the corresponding json file is required to contain the usingComponents definition segment.

In this case, the component's properties can be used to receive parameters for the page, such as accessing page /pages/index/index?paramA=123&paramB=xyz, and if the property paramA or paramB is declared, they are assigned the value of 123 or xyz.

The life cycle method of the page (that is, the method that begins with on) should be written in the methods definition paragraph.

Code Sample

One benefit of using the Component constructor to construct a page is that you can use behaviors to extract code snippets that are common to all pages.

For example, if you execute the same piece of code when all pages are created and destroyed, you can extract this code into behaviors.

Code Sample

# 2.2 Intercomponential communication and events

# 2.2.1 Inter-component communication

There are several basic ways of communicating between components.

  • FXML Data Binding: Used to set data for specified properties of the parent component to the child component, and only JSON-compatible data can be set (as of base library version 1.0.0, functions can also be included in the data).
  • Event: Used by child components to pass data to parent components, arbitrary data can be passed.
  • If the above two methods are not sufficient, the parent component can also obtain the child component instance object through the this.selectComponent method, which allows direct access to any of the component's data and methods.

# 2.2.2 Listen for events

The event system is one of the primary modes of communication between components. Custom components can trigger arbitrary events, and pages that reference components can listen for them.

The method of listening for custom component events is exactly the same as the way you listen for base component events:

Code Sample

# 2.2.3 Trigger event

When a custom component triggers an event, you need to use the triggerEvent method, specifying the event name, detail object, and event options:

The options for triggering an event include:

Option Name Type Required The default value is Description
bubbles Boolean No false Whether the event is bubbling
composed Boolean No false If the event can cross component boundaries, when false, the event will only fire on the node tree that references the component, not into any other component's internal
capturePhase Boolean No false Whether the event has a capture phase

# 2.2.4 Get the component instance

You can call this.selectComponent in the parent component to get an instance object of the child component (the plug-in's custom component will return null).

The call requires passing in a matching selector, such as this.selectComponent(".my-component").

In the example above, the parent component will get a child component instance object with a class of my-component, that is, this of the child component.

Enables support for the export definition segment in the custom component, which can be used to specify the return value when the component is called by selectComponent.

Code Sample

In the example above, when the parent component gets a child component instance with the-id, it gets the object { myField: 'myValue' } .

# 2.3 Component Lifecycle

The lifecycle of a component refers to some of the components' own functions that are automatically triggered at special points in time or when some special framework event is encountered.

Among them, the most important life cycle is created, attached, detached, containing the most important point in time of a component instance life flow.

  • When a component instance has just been created, the created lifecycle is triggered. At this point, the component data this.data is the data defined in the Component constructor. *** You cannot call setData **at this time. Typically, this lifecycle should only be used to add some custom property fields to component this.
  • After the component is fully initialized and enters the page node tree, the attached lifecycle is triggered. At this point, this.data has been initialized to the current value of the component. This lifecycle is useful, and most of the initialization work can be done at this time.
  • After a component leaves the page node tree, the detached lifecycle is triggered. When exiting a page, detached is triggered if the component is still in the page node tree.

# 2.3.1 Defines the lifecycle method

Lifecycle methods can be defined directly in the first level parameters of the Component constructor.

Starting with version 1.0.2 of the MiniApp Base Library, the lifecycle of a component can also be declared in the lifetimes field (which has the highest priority).

Code Sample

Lifecycle methods can also be written in behaviors without overwriting lifecycles of the same name in other behaviors. Note, however, that if a component references the same behavior directly or indirectly multiple times, the lifecycle function in that behavior will only execute once in a single execution time.

The full range of lifecycles available is shown in the following table:

Lifecycle Parameter Description Minimum version
created None Executes when the component instance has just been created 1.0.0
attached None Performs a when a component instance enters the page node tree 1.0.0
ready None Executes the after the component finishes laying out the view layer 1.0.0
detached None Performs when a component instance is removed from the page node tree 1.0.0
error Object Error Executes whenever a component method throws an error 2.1.7

# 2.4 behaviors

Behaviors are features for code sharing between components, similar to "mixins" or "traits" in some programming languages.

Each behavior can contain a set of properties, data, lifecycle functions, and methods. When a component references it, its properties, data, and methods are incorporated into the component, and lifecycle functions are called at the appropriate time. Each component can reference multiple behaviors, and behaviors can refer to other behaviors.

# Used in 2.4.1 components

When components are referenced, they can be listed one by one in the behaviors definition segment.

Code Sample

In the example above, my-behavior is included in the definition of the my-component component, and the my-behavior structure is:

  • Attribute: myBehaviorProperty
  • Data field: myBehaviorData
  • Method: myBehaviorMethod
  • Lifecycle functions: attached, created, ready

This will cause the my-component to finally structure as:

  • Attributes: myBehaviorProperty, myProperty
  • Data fields: myBehaviorData, myData
  • Method: myBehaviorMethod, myMethod
  • Lifecycle functions: attached, created, ready

When a component triggers a lifecycle, the preceding example of a lifecycle function executes in the following order:

  1. [my-behavior] created
  2. [my-component] created
  3. [my-behavior] attached
  4. [my-component] attached
  5. [my-behavior] ready
  6. [my-component] ready

For detailed rules, refer to override and combine rules for fields of the same name.

# 2.4.2 Override and combine rules for fields with the same name

The component and the behavior it references can contain fields with the same name, which are treated as follows:

  • If there are properties or methods with the same name:
    1. If the component itself has this property or method, the component's property or method overrides the property or method of the same name in the behavior;
    2. If the component itself does not have this property or method, defining a property or method of the behavior later in the behaviors field of the component overrides the previous property or method of the same name;
    3. On the basis of 2, if there is a nested reference to behavior, the rule is: the parent behavior overrides the property or method of the same name in the child behavior.
  • If there is a data field with the same name:
    • If the data fields with the same name are all object types, object merging will occur;
    • Data overlay occurs in the remaining cases, with the following rules: component > parent behavior > child behavior, later behavior > higher behavior. (High priority overrides low priority, largest is the highest priority)
  • The lifecycle functions do not overwrite each other, but are called one by one at the corresponding trigger time:
    • For different life cycle functions, follow the order of execution of component life cycle functions;
    • For the same kind of lifecycle function, the following rules are followed:
      • behavior takes precedence over component execution;
      • Child behavior takes precedence over parent behavior execution;
      • The higher behavior takes precedence over the lower behavior execution;
    • If the same behavior is referenced multiple times by a component, its defined lifecycle function will only be executed once.

# 2.5 Relationships Between Components

# 2.5.1 Define and use relationships between components

Sometimes it is necessary to implement components such as:

In this example, custom-ul and custom-li are custom components that have a relationship with each other, and communication with each other is often complex. At this point, adding the relations definition segment to the component definition can solve such a problem.

Sample Code

note

The relations definition must be included in both component definitions or it will not take effect.

# 2.5.2 Associates a class of components

Sometimes, what needs to be associated is a class of components, such as:

The custom-form component wants to associate the two components, custom-input and custom-submit. At this point, if both components have the same behavior:

In the relationship relationship definition, you can use this behavior in place of the component path as the target node for the association:

# 2.5.3 relations defines the segment

The relations definition segment contains the path of the target component and its corresponding options, which can be included in the following table.

Option Type Required Description
type String Yes The relative relationship of the target component, with optional values of parent , child , ancestor , descendant ,
linked Function No A relational lifecycle function that fires when a relationship is established in a tree of page nodes,
linkChanged Function No A relational lifecycle function that fires when a relationship changes in the page node tree, triggered
unlinked Function No A relational lifecycle function that fires when a relationship leaves the page node tree, triggered
target String No If this is set, it represents the behavior that the associated target node should have, and all component nodes that own this behavior are associated with

# 2.6 Data Listener

Data listeners can be used to listen for and respond to changes in any property and data field. Support for the MiniApp Base Library version 2.0.11 begins.

# 2.6.1 uses a data listener

Sometimes, when some data fields are set by setData, something needs to be done.

For example, this.data.sum is always the sum of this.data.numberA and this.data.numberB. At this point, you can use the data listener to do the following.

# 2.6.2 Listen for field syntax

The data listener supports listening for changes in properties or internal data, and can listen to multiple at the same time. SetData triggers each listener at most once.

At the same time, the Listener can listen for subdata fields, as shown in the following example.

If you need to listen for changes in all child data fields, you can use the wildcard character **.

In particular, you can listen to all setData using only the wildcard character **.

prompt

  • The data listener listens to the data fields involved in setData, and even if the values of these data fields do not change, the data listener will still be triggered.
  • If you use setData in a data listener function to set the data field itself to listen, it may cause an endless loop that requires special attention.

# 2.7 Pure data fields

Pure data fields are data fields that are not used for interface rendering and can be used to improve page update performance.

# A pure data field in component data

In some cases, fields in some data (including fields set by setData) are neither displayed on the interface nor passed to other components, only used inside the current component.

At this point, you can specify such data fields as "pure data fields", which will only be recorded in this.data, without participating in any interface rendering process, which will help improve page update performance.

The way to specify a "pure data field" is to specify pureDataPattern as a regular expression in the options definition section of the Component constructor, and fields whose fields name match this regular expression become pure data fields.

Code example:

The data-only fields in the above components are not applied to FXML:

# Pure data fields in component properties

Attributes can also be specified as pure data fields (following the regular expression of pureDataPattern).

A data-only field in a property can receive an externally passed property value just like a normal property, but it cannot be used directly in the component's own FXML.

Code example:

Note: The property observer for a pure data field in a property is never triggered! If you want to listen for property value changes, use a data listener instead.

You can also configure pureDataPattern in the json file of the page or custom component (so that you do not need to configure it in the options of the js file). In this case, its value should be written as a string:

# Use a data listener to listen for data-only fields

Data listeners can be used to listen for pure data fields (as with normal data fields). In this way, the interface can be changed by listening and responding to changes in pure data fields.

The following example is a custom component that converts a JavaScript timestamp to a readable time.

Preview the effect in the developer tools

Code example:

# 2.8 Abstract nodes

# Use abstract nodes in components

Sometimes, some nodes in a custom component template whose corresponding custom components are determined not by the custom component itself, but by the caller of the custom component. At this point, you can declare this node as an "abstract node".

For example, we now implement a "selectable-group" component, which can place a custom-radio or a custom-checkbox. The fxml for this component can be written like this:

Code example:

Where "selectable" is not any component declared in the usingComponents field of the json file, but an abstract node. It needs to declare in the componentGenerics field:

# Use components that contain abstract nodes

When using the selectable-group component, you must specify which component the "selectable" is:

Thus, when generating an instance of this selectable-group component, the "selectable" node generates an instance of the "custom-radio" component. Similarly, if used like this:

The "selectable" node generates an instance of the "custom-checkbox" component.

Note: The above custom-radio and custom-checkbox need to be included in the usingComponents definition section of this fxml corresponding json file.

# The default component for abstract nodes

An abstract node can specify a default component, and when a concrete component is not specified, an instance of the default component is created. The default component can be specified in the componentGenerics field:

# Precautions

  • In the generic reference to the node generic:xxx="yyy", the value yyy can only be a static value and cannot contain data binding. Therefore, the abstract node feature is not suitable for scenarios where node names are dynamically determined.

# 2.9 Custom Component Extensions

To better customize the functionality of a custom component, you can use the custom component extension mechanism

# Effect after extension

In order to better understand the effect of the extension, let's take an example:

It can be found through examples that the extension of the custom component actually provides the ability to modify the custom component definition segment, and the above example is to modify the content of the data definition segment in the custom component.

# Use extensions

The Behavior() constructor provides a new definition segment definitionFilter to support custom component extensions. A definitionFilter is a function that, when called, injects two arguments, the first being the definition object of the component/behavior that uses the behavior, and the second parameter being a list of definitionFilter functions for the behavior used by the behavior.

Here's an example:

The preceding code declares 1 custom component and 3 behaviors, each of which uses a definitionFilter definition segment. Then in the order of declarations, the following things will happen:

To summarize simply, the definitionFilter function can be understood to mean that when A uses B, the A declaration calls B's definitionFilter function and passes in A's definition object for B to filter. At this point, if B also uses C and D, then B can decide for itself whether to call the definitionFilter functions of C and D to filter A's definition objects.

# Code Example

The following is an extension that makes it easy to implement the calculated property functionality of a custom component:

To use in a component:

The implementation principle is very simple, the existing setData is encapsulated twice, the value of each field in the computed is calculated at each setData, and then set to data to achieve the effect of calculating the property.

# 2.10 Get updated performance statistics

If you want to know the overhead of setData incurring interface updates, you can use the Update Performance Statistics interface. It returns a timestamp of the timestamp of the major update step that occurred in each update and can be used to roughly estimate the performance of custom component (or page) updates. For example:

The setUpdatePerformanceListener method accepts an options object and the callback function listener as arguments.

Where the options object contains the following fields:

Field Type Description
withDataPaths Boolean Whether to return changed data field information

Listeners returns a res object that represents an update process initiated by setData. Depending on the timing of the setData call, the update process can be broadly divided into three categories:

Each successful setData call results in an update process that causes the listener to call back once. However, it is difficult to determine which type of update process setData triggers, and the performance of the update is not necessarily related to what kind of update it is, but their return value parameters are different.

Res contains the following fields:

Field Type Description
updateProcessId Number  此次  更新过程的 ID
parentUpdateProcessId Number For child updates, returns the update process ID
isMergedUpdate Boolean 是否是被合并更新,如果是, 则 updateProcessId 表示被合并到的更新过程 ID
dataPaths Array The data field information for this update returns only
pendingStartTimestamp Number The timestamp when the update entered the wait queue
updateStartTimestamp Number Updates the timestamp at the start of the operation
updateEndTimestamp Number Updates the timestamp at the end of the operation

Illustrate:

  • setUpdatePerformanceListener will only activate the statistics of the current component or page, parentUpdateProcessId may be the update process ID of other components or pages without being called back by statistics, if you want to know all the update processes in the page, you need to call setUpdatePerformanceListener in all components;
  • The stat itself has a little overhead, if you want to disable the stat, call setUpdatePerformanceListener when passing in the second argument listener as null.
Last update: 2022/08/16, 21:48:49
View
Storage

← View Storage→

Copyright © 2020-2024 Neuxnet
  • Follow System
  • Light Mode
  • Dark Mode
  • Reading Mode