Component Development
Components are reusable UI elements that encapsulate structure, style, and behavior. They help in building modular and maintainable mini programs. This guide covers the essentials of component development.
Component Structure
A mini program component typically consists of four files:
- JavaScript File (.js): Contains the component logic
- Template File (.wxml/.axml/.swan): Contains the component structure
- Style File (.wxss/.acss/.css): Contains the component styling
- Configuration File (.json): Contains the component configuration
Creating a New Component
1. Create the Component Directory
First, create a new directory for your component in the components
folder:
components/
└── my-component/
2. Create the Component Files
Create the four required files in the component directory:
components/
└── my-component/
├── my-component.js
├── my-component.wxml
├── my-component.wxss
└── my-component.json
3. Configure the Component
In the component's JSON file, set "component": true
:
{
"component": true,
"usingComponents": {}
}
4. Register the Component
To use the component in a page, register it in the page's JSON file:
{
"usingComponents": {
"my-component": "/components/my-component/my-component"
}
}
Component JavaScript
The component JavaScript file defines the component instance, properties, data, and methods.
Basic Structure
// components/my-component/my-component.js
Component({
// Component properties (passed from parent)
properties: {
title: {
type: String,
value: 'Default Title'
},
items: {
type: Array,
value: []
}
},
// Component internal data
data: {
count: 0
},
// Component lifecycle
lifetimes: {
created() {
// Component instance created
console.log('Component created')
},
attached() {
// Component attached to page
console.log('Component attached')
},
ready() {
// Component rendering complete
console.log('Component ready')
},
moved() {
// Component position changed
console.log('Component moved')
},
detached() {
// Component detached from page
console.log('Component detached')
}
},
// Page lifecycle
pageLifetimes: {
show() {
// Page containing component shown
console.log('Page shown')
},
hide() {
// Page containing component hidden
console.log('Page hidden')
},
resize(size) {
// Page size changed
console.log('Page resized:', size)
}
},
// Component methods
methods: {
// Event handlers
handleTap() {
this.setData({
count: this.data.count + 1
})
// Trigger an event to the parent
this.triggerEvent('countchange', {
count: this.data.count
})
},
// Custom methods
reset() {
this.setData({
count: 0
})
}
}
})
Properties
Properties are data passed from the parent to the component:
properties: {
// Simple property
title: String,
// Property with type and default value
subtitle: {
type: String,
value: 'Default Subtitle'
},
// Property with observer
status: {
type: String,
value: 'normal',
observer(newVal, oldVal) {
console.log(`Status changed from ${oldVal} to ${newVal}`)
this.statusChanged(newVal)
}
}
}
Property types can be:
String
Number
Boolean
Object
Array
null
(accepts any type)
Data Management
Use this.setData()
to update the component data and trigger UI updates:
this.setData({
count: this.data.count + 1,
'user.name': 'John',
'items[0]': 'Updated Item'
})
Custom Events
Trigger events to communicate with the parent:
this.triggerEvent('customEvent', {
// Event detail data
value: this.data.count
}, {
// Event options
bubbles: false,
composed: false,
capturePhase: false
})
Component Template
The component template file defines the structure and layout of the component.
Basic Structure
<!-- components/my-component/my-component.wxml -->
<view class="component-container">
<view class="header">
<text class="title">{{title}}</text>
</view>
<view class="content">
<block wx:for="{{items}}" wx:key="index">
<view class="item">{{item}}</view>
</block>
</view>
<view class="footer">
<text>Count: {{count}}</text>
<button bindtap="handleTap">Increment</button>
</view>
</view>
Slots
Use slots to allow content insertion from the parent:
<!-- Default slot -->
<view class="container">
<view class="header">{{title}}</view>
<view class="content">
<slot></slot>
</view>
</view>
<!-- Named slots -->
<view class="container">
<view class="header">
<slot name="header"></slot>
</view>
<view class="content">
<slot name="content"></slot>
</view>
<view class="footer">
<slot name="footer"></slot>
</view>
</view>
In the parent page:
<!-- Using default slot -->
<my-component title="My Component">
<view>This content goes into the default slot</view>
</my-component>
<!-- Using named slots -->
<my-component title="My Component">
<view slot="header">Header Content</view>
<view slot="content">Main Content</view>
<view slot="footer">Footer Content</view>
</my-component>
Component Styling
The component style file contains CSS rules specific to the component.
Basic Structure
/* components/my-component/my-component.wxss */
.component-container {
padding: 20rpx;
border: 1rpx solid #eee;
border-radius: 10rpx;
}
.header {
margin-bottom: 20rpx;
}
.title {
font-size: 32rpx;
font-weight: bold;
}
.content {
margin-bottom: 20rpx;
}
.item {
padding: 10rpx;
border-bottom: 1rpx solid #eee;
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
}
Style Isolation
By default, component styles are isolated from the parent page. You can configure style isolation in the component's JSON file:
{
"component": true,
"styleIsolation": "isolated"
}
Style isolation options:
isolated
: Component styles don't affect parent, parent styles don't affect component (default)apply-shared
: Parent styles affect component, component styles don't affect parentshared
: Component styles affect parent, parent styles affect component
Component Configuration
The component configuration file contains settings specific to the component.
Basic Structure
{
"component": true,
"usingComponents": {
"sub-component": "/components/sub-component/sub-component"
},
"styleIsolation": "isolated"
}
Common Configuration Options
- component: Must be set to
true
for component files - usingComponents: Registers other components for use within this component
- styleIsolation: Controls how styles are isolated between component and parent
- componentGenerics: Defines generic components (similar to templates)
Advanced Component Features
Behaviors
Behaviors are similar to mixins, allowing code reuse across components:
// behaviors/my-behavior.js
export default Behavior({
properties: {
behaviorProperty: {
type: String,
value: 'Default Value'
}
},
data: {
behaviorData: 'Behavior Data'
},
methods: {
behaviorMethod() {
console.log('Behavior method called')
}
}
})
Using behaviors in a component:
import myBehavior from '../../behaviors/my-behavior'
Component({
behaviors: [myBehavior],
// Component properties, data, and methods
// These can override behavior properties, data, and methods
})
Relations
Define relationships between components:
Component({
relations: {
'../list-item/list-item': {
type: 'child', // or 'parent', 'ancestor', 'descendant'
linked(target) {
// Called when a related component is attached
console.log('Item linked:', target)
this.updateItems()
},
linkChanged(target) {
// Called when a related component's data changes
console.log('Item changed:', target)
this.updateItems()
},
unlinked(target) {
// Called when a related component is detached
console.log('Item unlinked:', target)
this.updateItems()
}
}
},
methods: {
updateItems() {
const items = this.getRelationNodes('../list-item/list-item')
console.log('Related items:', items)
}
}
})
Component Options
Configure component behavior with options:
Component({
options: {
multipleSlots: true, // Enable multiple named slots
addGlobalClass: true, // Allow global class names in the component
pureDataPattern: /^_/, // Properties starting with _ won't trigger UI updates
virtualHost: true // Component acts as a virtual node
}
})
Best Practices
- Keep Components Focused: Each component should have a single responsibility
- Design Clear APIs: Define clear properties and events for component interaction
- Document Components: Add comments explaining the component's purpose and usage
- Reuse Components: Create a library of reusable components
- Test Components: Test components in isolation
- Follow Naming Conventions: Use consistent naming for components, properties, and events
- Optimize Performance: Minimize unnecessary renders and data updates
Next Steps
Now that you understand component development, you can proceed to learn about: