Skip to content

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:

  1. JavaScript File (.js): Contains the component logic
  2. Template File (.wxml/.axml/.swan): Contains the component structure
  3. Style File (.wxss/.acss/.css): Contains the component styling
  4. 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:

json
{
  "component": true,
  "usingComponents": {}
}

4. Register the Component ​

To use the component in a page, register it in the page's JSON file:

json
{
  "usingComponents": {
    "my-component": "/components/my-component/my-component"
  }
}

Component JavaScript ​

The component JavaScript file defines the component instance, properties, data, and methods.

Basic Structure ​

javascript
// 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:

javascript
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:

javascript
this.setData({
  count: this.data.count + 1,
  'user.name': 'John',
  'items[0]': 'Updated Item'
})

Custom Events ​

Trigger events to communicate with the parent:

javascript
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 ​

html
<!-- 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:

html
<!-- 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:

html
<!-- 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 ​

css
/* 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:

json
{
  "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 parent
  • shared: Component styles affect parent, parent styles affect component

Component Configuration ​

The component configuration file contains settings specific to the component.

Basic Structure ​

json
{
  "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:

javascript
// 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:

javascript
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:

javascript
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:

javascript
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 ​

  1. Keep Components Focused: Each component should have a single responsibility
  2. Design Clear APIs: Define clear properties and events for component interaction
  3. Document Components: Add comments explaining the component's purpose and usage
  4. Reuse Components: Create a library of reusable components
  5. Test Components: Test components in isolation
  6. Follow Naming Conventions: Use consistent naming for components, properties, and events
  7. Optimize Performance: Minimize unnecessary renders and data updates

Next Steps ​

Now that you understand component development, you can proceed to learn about:

Connecting Multiple Platforms, Empowering Innovation