HomeDocs
Skip to main content

Custom Mini Program Components

Creating Custom Components

Developers can abstract functional modules within a page into custom components, enabling their use across different pages within the mini program. This practice enhances code reusability and reduces development costs.

Explanation: A custom component comprises four files (.dlt, .css, .js, .json). For example, considering a project structure with a custom component named "custom-component":

// Project structure containing the custom component "custom-component"
├── app.js
├── app.json
└── pages
└── components
├── custom-component.dlt
├── custom-component.css
├── custom-component.js
└── custom-component.json

To create a custom component, first declare it in the JSON file (setting the "component" field to true indicates that this set of files constitutes a custom component):

// Custom component configuration (custom-component.json)
{
"component": true
}

Similar to page development, creating a custom component involves writing the component's template in the .dlt file and importing its styles in the .css file, following a similar approach as for pages.

Code Example:

<!-- Template within the custom component (custom-component.dlt) -->
<view class="name"> {{name}} </view>
/* Styles for the custom component (custom-component.css) */
.name {
color: red;
}

In the custom component's .js file, use the Component() function to register the component and provide property definitions, internal data, and custom methods.

The property values and internal data of the component will be used to render the component's template. Properties can be passed into the component from its parent.

// Logic for the custom component (custom-component.js)
Component({
properties: {
name: {
type: String,
value: "hello world",
observer: function (newVal, oldVal) {
// Function to execute when the property changes (optional)
},
},
},
data: {
age: 1,
},
methods: {
tap: function () {},
},
});

Using Custom Components

Before using a registered custom component, you need to declare its usage in the JSON file of the page. Apart from using custom components within a page, you can also have a custom component reference another custom component, similar to how pages reference custom components.

Here's an example of using a custom component at the page level (pages/index/index):

// Project structure
├── app.js
├── app.json
└── pages
├──index
│ ├── index.dlt
│ ├── index.css
│ ├── index.js
│ └── index.json
└── components
├── custom-component.dlt
├── custom-component.css
├── custom-component.js
└── custom-component.json

You need to provide the tag name for each custom component along with its corresponding file path.

Tip:

  1. Custom Component File Path: Path to the directory containing the custom component's .dlt, .css, .js, and .json files, plus the base name of these files. In the example project structure above, this path would be /pages/components/custom-component.
  2. When creating custom components, it's recommended to keep the inner files (e.g., .dlt, .css, .js, .json) named the same as the custom component's directory.

Code Example:

// Page configuration (index.json)
{
"navigationBarTitleText": "Custom Mini Program Component Example",
"usingComponents": {
"custom-component": "/pages/components/custom-component"
}
}

With this setup, you can use the custom component in the page's .dlt file just like a basic component. The tag name corresponds to the custom component's tag, and the node's attributes are passed as property values to the component.

<!-- Page template (index.dlt) -->
<view>
<!-- Referencing the custom component within the page -->
<custom-component></custom-component>
</view>

The custom component's .dlt node structure, combined with data, will be inserted at the reference position.

Component Template

The syntax for the component's template is the same as that for a page's template. The component template, combined with component data, generates a node tree that's inserted at the reference position of the component.

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

Code Example:

<!-- Template within the custom component (custom-component.dlt) -->
<view class="wrapper">
<view bind:tap="onTap">Component internal node: {{val}}</view>
<slot></slot>
</view>
<view>
<custom-component>
<view>Content inserted into the component slot</view>
</custom-component>
</view>

Template Data Binding (Passing Values from Page to Custom Component)

Similar to regular .dlt templates, you can use data binding to dynamically pass data to a child component's properties.

<!-- Page containing the custom component (index.dlt) -->
<view>
<custom-component :message="msg"> </custom-component>
</view>
// JavaScript for the page containing the custom component (index.js)
const app = getApp();

Page({
data: {
msg: "pageOldMessage",
},
changeData: function () {
this.setData({
msg: "pageNewMessage",
});
},
});

In the above example, triggering changeData will update the message passed to the custom component to "pageNewMessage".

// JavaScript for the custom component (custom-component.js)
Component({
properties: {
message: {
type: String,
value: "val",
observer: function (newVal, oldVal) {
// "====newVal, oldVal====", world, hello
},
},
},
data: {},
});
<!-- Template within the custom component (custom-component.dlt) -->
<view> {{message}} </view>

The message field rendered by the custom component comes from the msg field in the page's data. When data.msg changes in the page, the message in the custom component synchronizes accordingly.

Communication between Custom Component and Page (Modifying Page Data)

Communicating with the Parent Component Using the triggerEvent Method

<!-- Page containing the custom component (index.dlt) -->
<view>
<view>{{pageData}}</view>
<custom-component bindmyevent="change" :message="pageData"></custom-component>
</view>
// JavaScript for the page containing the custom component (index.js)
Page({
data: {
pageData: "hello",
},
change: function (data) {
// Function to change data in the custom component
this.setData({
pageData: data.val,
});
},
});
// JavaScript for the custom component (custom-component.js)
Component({
properties: {
message: {
type: String,
value: "val",
observer: function (newVal, oldVal) {
// "====newVal, oldVal====", world, hello
},
},
},
data: {},
methods: {
onTap: function () {
var myEventDetail = {
val: "world",
};
var myEventOption = {};
this.triggerEvent("myevent", myEventDetail, myEventOption);
// The event name here is "myevent"; it is bound to "bindmyevent" on the component tag, not ":myevent" or "bind:myevent"
},
},
});

📢 Note:

When binding the event name with triggerEvent, use the "bind" keyword in the tag, and do not use ":" to bind the event name. For example, myevent is bound using bindmyevent="functionNameDefinedInPage".

Component Constructor

Code Example

// JavaScript for the custom component (custom-component.js)
Component({
properties: {
propName: {
type: String,
value: "val",
observer: function (newVal, oldVal) {
// Function to execute when the property changes (optional)
},
},
},

data: {
val: "hello",
}, // Private data for template rendering
pageLifetimes: {
show: function () {
// Triggered when the component's parent page is shown
console.log("==Component=pageLifetimes=show====");
},
hide: function () {
// Triggered when the component's parent page is hidden
console.log("==Component=pageLifetimes=hide====");
},
resize: function () {
// Triggered when the component's parent page changes orientation (not supported yet)
console.log("==Component=pageLifetimes=resize====");
},
},
lifetimes: {
created: function () {
// Executed when the component instance enters the page's node tree
console.log("==Component=lifetimes=created====");
},
attached: function () {
// Executed when the component instance enters the page's node tree
console.log("==Component=lifetimes=attached====");
},
ready: function () {
// Executed when the component instance enters the page's node tree
console.log("==Component=lifetimes=ready====");
},
detached: function () {
// Executed when the component instance is removed from the page's node tree
console.log("==Component=lifetimes=detached====");
},
},
methods: {
onTap: function () {
this.setData({
val: "world",
});
},
},
});

The lifecycle of a custom component can be referenced in the Mini Program lifecycle documentation

Using sjs Within Custom Components

Custom components support using sjs. Refer to the Mini Program SJS documentation.

Usage Example

// Project structure
├── app.js
├── app.json
└── pages
└── index
├── index.dlt
├── index.css
├── index.js
└── index.json
└── components
├── custom-component.dlt
├── custom-component.css
├── custom-component.js
├── componentSjs.sjs
└── custom-component.json

Code Example

<!-- Template within the custom component (custom-component.dlt) -->
<view class="wrapper">
<view class="title" bind:tap="onTap">Component internal node</view>
<slot></slot>
<view>message: {{componentSjs.message()}}</view>
<view>{{val}}</view>
<view bind:tap="{{componentSjs.tapitem}}">tapitem</view>
<import-sjs module="componentSjs" src="./componentSjs.sjs"></import-sjs>
</view>
// componentSjs.sjs
export default {
message: function () {
return "hello world ";
},
tapitem: function (event, instance) {
instance.setStyle({
color: "#ff0",
});
},
};
Privacy agreementDeveloper agreementcontact us: developer_service.mi@transsion.com © 2024 MiniApp. All Rights Reserved.