Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Step-by-Step Example for Building a Basic WeChat Mini Program

Tech 2

Initial Project Structure

After creating a new Mini Program project, the developer tool automatically generates a default directory structure:

  • pages directory: Stores all page files for the Mini Program, each page gets its own dedicated subdirectory here (like the default index page)
  • utils directory: Holds shared utility JavaScript code. You can expose functions and objects via module.exports, then import them anywhere with require() for code reuse
  • app.js (required): The global entry JavaScript file. Missing this file will throw errors. Its used to listen to Mini Program lifecycle events and declare global variables
  • app.json (required): Global configuration file, also required to avoid errors. It configures page routing, the default homepage, window behavior and other global settings
  • app.wxss: Global stylesheet for the Mini Program, equivalent to standard global CSS
  • project.config.json: IDE-specific local configuration, can be ignored for core development work

Add Custom Pages

Beyond the default index and logs pages, we will add two new pages: home (our homepage) and item (our detail page for navigation testing):

  1. Right-click the pages directory, select New > Directory, name it home
  2. Right-click the new home directory, select New > Page, name it home. The IDE will automatically generate all four required files for the page: .js, .json, .wxml, .wxss

For context: .wxml is analogous to HTML for web, .wxss is equivalent to CSS, .js handles page logic, and .json stores page-specific window configuration (like title bar text and background color).

Repeat the same process to create the item page.

Create A Static Asset Directory

WeChat Mini Program does not enforce a strict structure for static assets, but a common convention is to store them in a dedicated assets folder. Create a top-level assets directory in your project root, then add an images subdirectory inside assets to store image files. Reference these assets using relative or root-relative paths in your code.

Note: WeChat Mini Program enforces a total package size limit for production releases, so avoid storing large assets like high-resolution images directly in your project.

Configure Tab Bar Navigation

Open app.json (the global configuration file), and add a tabBar configuration after the existing window object. Don't forget to add a trailing comma after window to avoid JSON syntax errors.

The tabBar configuration accepts these core parameters:

  • backgroundColor: Background color of the tab bar
  • color: Default text color for unselected tabs
  • selectedColor: Text color for the currently active tab
  • list: An array of tab configuration objects, each object contains:
    • pagePath: File path to the target page
    • text: Display title of the tab
    • iconPath: Path to the default tab icon
    • selectedIconPath: Path to the icon for the selected state

Sample configuration:

"tabBar": {
  "backgroundColor": "#ffffff",
  "color": "#7f7f7f",
  "selectedColor": "#e64a19",
  "list": [
    {
      "pagePath": "pages/home/home",
      "text": "Home",
      "iconPath": "/assets/images/home.png",
      "selectedIconPath": "/assets/images/home-active.png"
    },
    {
      "pagePath": "pages/index/index",
      "text": "Profile",
      "iconPath": "/assets/images/user.png",
      "selectedIconPath": "/assets/images/user-active.png"
    }
  ]
}

Make sure you add the corresponding icon files to your assets/images directory for the tab bar to render correctly.

Build The Home Page Layout

We'll start with a static layout, then convert it to dynamic data rendering. Open pages/home/home.wxml and replace the default content with this markup:

<!--pages/home/home.wxml-->
<view class="card-group">
  <view class="content-card">
    <navigator url="../item/item">
      <image class="card-cover" src="https://7n.w3cschool.cn/attachments/cover/cover_html.png?t=15547020"></image>
      <view class="card-title">HTML Tutorial</view>
    </navigator>
  </view>

  <view class="content-card">
    <navigator url="../item/item">
      <image class="card-cover" src="https://7n.w3cschool.cn/attachments/cover/cover_html5.png?t=1314520"></image>
      <view class="card-title">HTML5 Tutorial</view>
    </navigator>
  </view>
</view>

Key notes for Mini Program markup:

  • view is the primary layout container, equivalent to div in standard HTML
  • Use image instead of img for embedding images in Mini Programs
  • navigator handles in-app page navigation, similar to the a tag in HTML, and uses the url attribute to set the target path. External domain navigation requires enterprise verification and domain whitelisting.

Next add styles. Open home.wxss and add the following flexbox layout styles:

/* pages/home/home.wxss */
.card-group{
  display:flex;
  flex-wrap:wrap;
  padding:10rpx 12rpx;
}
.content-card{
  width:339rpx;
  margin:0rpx 12rpx 30rpx 12rpx;
  flex-shrink:0;
}
.card-cover{
  width:100%;
  height:180rpx;
  border-radius:8rpx;
}
.card-title{
  font-size:26rpx;
  line-height:1.5;
  margin-top:10rpx;
  color:#333333;
  text-align:center;
}

Important: Mini Program image elements require an explicit height, they do not auto-size to content. If you don't set a height, the image will not render correctly.

Set The Default Homepage

By default, the first entry in the pages array in app.json is set as the Mini Program homepage. To set home as your homepage, simply move the pages/home/home entry to the first position in the pages array.

Note: Each page path in the pages array maps to a JavaScript file with the same name. If the file is missing, the Mini Program will throw a runtime error.

Add Dynamic Data Rendering

Right now our content is hardcoded in the markup. Let's update it to pull data from the page's JavaScript data object. For this example, we use static local data instead of an external API response.

Note: To load external images or call external APIs, you must add the corresponding domain to your Mini Program's whitelist in the WeChat backend.

Open home.js and update the default data object to store our content list:

/**
 * Page initial data
 */
data: {
  contentList: [
    { 'cover': 'https://7n.w3cschool.cn/attachments/cover/cover_html.png?t=15547020', 'title': 'HTML' },
    { 'cover': 'https://7n.w3cschool.cn/attachments/cover/cover_html5.png?t=1314520', 'title': 'HTML5' },
    { 'cover': 'https://example.com/css-cover.png', 'title': 'CSS' },
    { 'cover': 'https://example.com/css3-cover.png', 'title': 'CSS3' },
  ]
},

Update home.wxml to use list rendering with dynamic data, and add event binding for navigation:

<!--pages/home/home.wxml-->
<view class="card-group">
  <view class="content-card" wx:for="{{contentList}}" wx:key="title" >
    <navigator data-title="{{item.title}}" bindtap="openDetailPage" >
      <image class="card-cover" src="{{item.cover}}"></image>
      <view class="card-title">{{item.title}}</view>
    </navigator>
  </view>
</view>

We use wx:for to loop over the contentList array and render one card per entry. To pass custom parameters from markup to event handlers in Mini Programs, use the data-* atribute syntax. Note that custom parameter names can not use camelCase.

Add Navigation Event Handler

Add the event handler to home.js after the default lifecycle methods (don't forget to add a trailing comma after the previous method):

/**
 * Navigate to detail page with selected title parameter
 */
openDetailPage: function(e) {
  const pageTitle = e.currentTarget.dataset.title;
  wx.navigateTo({
    url: `../item/item?title=${pageTitle}`
  })
}

This handler extracts the custom title parameter from the event target, then calls wx.navigateTo to navigate to the detail page with the parameter appended to the URL.

Retrieve Parameter In Detail Page

Open item.wxml and add a text element to display the received title:

<!--pages/item/item.wxml-->
<text>{{title}}</text>

Open item.js and update the onLoad lifecycle method to retrieve the parameter from the navigation options:

/**
 * Lifecycle function -- listen for page load
 */
onLoad: function (options) {
  this.setData({
    title: options.title
  })
},

We get the title parameter from the options object passed to onLoad, then use setData to update the page's data, which automatically updates the displayed content on the page.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.