Skip to main content

Hands-on Store Mini Program Development Guide

Overview

This article uses a store mini program development project as an example to introduce the preparatory work during WeChat Mini Program development, the creation process of the mini program, the functionality of each file in the directory, and the cloud development features used during development, such as cloud storage, databases, and cloud functions.

Note

The source code materials involved in this tutorial example have been properly authorized.

Preparation

  1. Register for Tencent Cloud.
  2. Mini Program with Cloud Development enabled. For details, please refer to Quick Start for WeChat Mini Program.

Operation Process

The specific operation process can be divided into the following 4 steps. For more details, please refer to the example.

Project Directory

FileDescription
Configuration File .json
  • Project configuration file `app.json`: used to configure the paths of each page, set the window and bottom navigation bar.
  • Page configuration file such as `index.json`: used to implement personalized settings for the respective page.
  • Template File .wxmlCommonly used page template files such as `index.wxml`, similar to HTML, utilize a tag-based language to design interface components and event systems, thereby constructing the page structure.
    Style File .wxss
  • Project style file `app.wxss`: used to configure global styles.
  • Page style file such as `index.wxss`: used to configure personalized styles for the page, overriding global styles within its page.
  • Logic File .jsLogic files are used to implement the business logic features of pages, such as data acquisition, determination, page prompts, and other functionalities, all of which are implemented by writing methods in the logic files.

    Environment Configuration

    This article primarily focuses on explaining the project configuration files app.json and app.js. For more details on project configuration file code, refer to app.json Configuration and app.js Configuration.

    Step 1: Create Pages Required for the Project

    First, conduct requirements analysis:

    • A store requires at least one home page to display available products to users.
    • A product detail page is used to present information about a single product.
    • A shopping cart is used to hold desired items for users.

    Therefore, we need to configure the content in the pages section of the Mini Program project configuration file app.json. After inputting the corresponding paths, the developer tools will generate the page files at those paths.

    "pages":[
    "pages/index/index",
    "pages/cart/cart",
    "pages/detail/detail"
    ],

    Step 2: Configure the Store's Navigation Bar

    After generating the pages in Step 1, you need to add them to the navigation bar for user convenience. In app.json, add a tabBar property. Since the store consists of two main sections: the home page and shopping cart, add two buttons in the list property of the tabBar, configuring their page paths, titles, and icons.

    "tabBar": {
    "selectedColor": "#f00",
    "list": [
    {
    "pagePath": "pages/index/index",
    "text": "Home",
    "iconPath": "./SweetDumplingSauce/1.jpeg",
    "selectedIconPath": "./SweetDumplingSauce/3.jpeg"
    },
    {
    "pagePath": "pages/cart/cart",
    "text": "Shopping Cart",
    "iconPath": "./SweetDumplingSauce/2.jpeg",
    "selectedIconPath": "./SweetDumplingSauce/4.jpeg"
    }
    ]
    }

    The following figure shows the effect.

    Step 3: Configure the CloudBase environment

    1. Go to the WeChat DevTools > Cloud Development Console page and copy the Environment ID.

    2. Call the API in app.js and pass the environment ID from the Cloud Development Console to wx.cloud.init, enabling the project to access data and resources in the console.

    // app.js
    App({
    onLaunch: function () {
    wx.cloud.init({
    env: env: "xxxxx", // Enter your environment ID
    });
    },
    globalData: {
    userInfo: null,
    },
    });

    Step 4: Create a database

    Store the mall's products in a database to facilitate product display on subsequent pages.

    1. Go to the WeChat Developer Tools > Cloud Development Console > Database page. Create three collections: carts, goods, and orders.

    2. Go to the goods collection, click Add Record to add some initial information. The attributes for each data record are as follows:

    • count: Product quantity.
    • imageSrc: Product image, obtained from cloud storage.
    • price: Product price.
    • tags: Product category tags.
    • title: Product name.
    Note

    Product images need to be imported into cloud storage first to generate the image location, facilitating the invocation of image data during development.

    Step 5: Import images to cloud storage

    1. Go to the WeChat Developer Tools > Cloud Development Console > Storage page.

    2. Click New Folder and name it goods.

    3. Go to the goods folder, click Upload File, and upload the required images. These files can be referenced in the project using FileID.

    Step 6: Create cloud function

    1. Create a folder named cloudfunction for cloud functions in the directory, then set the cloudfunctionRoot property value to "cloudfunction/" in project.config.json.

    2. When the files in the cloudfunction directory turn green, it indicates that the cloud function initialization is complete. Right-click the folder and select New Node.js Cloud Function to create a cloud function. The result is as shown below:

    Building the Store Homepage

    This article primarily focuses on the explanation of the store homepage files index.js and index.wxml. For more details on project configuration file code, refer to index.js Configuration and Frontend Page index.wxml.

    The preview of the store homepage is as shown below:

    Step 1: Access the Cloud Database

    In the index.js file of the store page, call wx.cloud.database().collection() to obtain a reference to the product database in the current cloud development environment.

    // Obtain the database
    const db = wx.cloud.database()
    // Obtain the collection
    const goods_col = db.collection('goods')
    const carts_col = db.collection('carts')
    Note

    When accessing database data, errors frequently occur, or when changing data in the console, errors persistently occur. This is generally a permission issue with the cloud database. By setting all permissions of the database to true through custom rule permissions, such errors can be resolved.

    Step 2: Load Product List Data

    In the index.js file of the homepage, write the logic for loading the product data list, set the loading animation to be hidden, and specify the number of products to display at once in the list. Access good_col to read product data.

      // Load list data
    async loadListData(){
    const LIMIT = 5
    let{_page,goods}=this.data//0

    /*wx.showLoading({// Loading
    title: 'Loading...',
    })*/
    await ml_showLoading

    let res = await goods_col.limit(LIMIT).skip(_page * LIMIT).get()

    //wx.hideLoading()// Hide loading
    await ml_hideLoading
    // Manually stop pull-to-refresh
    wx.stopPullDownRefresh()

    console.log('List data', res.data)
    this.setData({
    goods :[...goods,...res.data],//追加,与之前数据拼接: goods :[...goods,...res.data],// Append, concatenate with previous data
    _page: ++_page,
    hasmore : res.data.length === LIMIT
    })
    },

    Code Explanation

    • res: Variable that stores the return value of querying the product database.
    • limit(): Limits the number of products displayed at a time.
    • LIMIT: The initial value is 5.
    • _page: Initial value is 0, and it will be incremented by one iteratively.
    • _page*LIMIT: Indicates skipping a number of elements from the database to start fetching data.
    • setData(): Concatenates the product data retrieved each time.

    Step 3: Set Up Pull-up Event for Product Data Loading

    First, limit the number of data items retrieved at a time in the data loading function, which can be defined as accessing five product information entries from the cloud each time. When loading new data, call wx.showLoading() to display a loading prompt. After loading completes, to enhance user experience, add an onReachBottom() event handler that invokes the product data loading function.

      onReachBottom(){
    // No more data to refresh.
    if(!this.data.hasmore)
    {
    /*wx.showToast({
    title: title: 'No more data',
    icon : "none"
    })*/
    ml_showToast('No more data')
    return console.log('No more data')
    }
    console.log('Pull to refresh')
    this.loadListData()
    },
    Note

    数据加载函数中由于一次加载只有五条信息,所以需要在数据加载函数的末尾,将之前加载的数据与本次函数调用加载的数据,用 setData 进行一个拼接,保障用户在下滑时还可以看到前面的商品数据。

    Step 4: Configure Product Loading Completion Prompt

    1. Set a bool variable with an initial value of true. In the data loading function, determine whether the data obtained from the database is less than the limited number of data to be retrieved. If it is less, it indicates that the data in the database has been fully loaded, and change the value of the bool variable to false; otherwise, it has not been fully loaded.
    2. Then, in the pull-up event handler function, set a listener at the beginning. When it detects that the bool variable is false, call wx.showToast() to indicate no more data is available to load, and directly return from the pull-up loading function.
    Note

    Since wx.showToast() can be used in multiple places, encapsulate it so that it can be directly imported and called on the required pages.

    Step 5: Set Up Pull-down Event to Refresh the Page

    1. Use the onPullDownRefresh() event handler function to reset all values to their initial state and re-invoke the latest data loading function. In the data loading function, manually stop the pull-down refresh by calling wx.stopPullDownRefresh().
      //Pull to refresh
    onPullDownRefresh(){
    this.setData({
    goods : [],
    _page :0,
    hasmore :true
    })
    this.loadListData()
    console.log('Pull to refresh')
    },
    1. Before this, you also need to configure in index.json by setting "enablePullDownRefresh" to true by default; then change the background loading dots (default white) to gray.
    {
    "usingComponents": {},
    "enablePullDownRefresh" : true,
    "backgroundTextStyle" : "dark"
    }

    Step 6: Register the Place Order Click Event

    Set the catchtap attribute on the order button of the mall homepage to implement the add-to-cart function.

    Danger

    bindtap attribute cannot be used here because using bindtap will bubble up and go to the product details page when clicked; catchtap, however, will not redirect, but directly trigger the function to add the product to the shopping cart, then pass the product data from the order clicked on the homepage to the shopping cart page.

    The implementation of the add to cart feature also needs to determine whether the product to be ordered already exists in the shopping cart. Using the ID passed from the order on the homepage, obtain data in the shopping cart database:

    • If the data is obtained successfully, it indicates that the product is already in the shopping cart. Call update() to increment the num by one, and invoke the encapsulated wx.showToast() to prompt that the product has already been added.
    • If the data fails to be obtained, it indicates that the product has not been added to the shopping cart. You need to add the product data to the shopping cart database by calling add() to include the product data. The data attributes include:
    • _id: Product ID
    • imageSrc: Product image
    • price: Product price
    • title: Product name

    After a successful addition, call the previously encapsulated wx.showToast() to prompt successful addition. The code implementation is as follows:

    Add to Cart
    async addCart(e){
    // Obtain the product
    let { item }=e.currentTarget.dataset
    console.log('item' ,item)
    // Check if the product is in the shopping cart
    try{
    let res =await carts_col.doc(item._id).get()
    console.log('has value', res)
    // has value
    await carts_col.doc(item._id).update({
    data:{
    num: db.command.inc(1)
    }
    })
    }
    catch(err){
    console.log('no value')
    // Add the product to the shopping cart
    await carts_col.add({
    data :{
    _id :item._id,
    imageSrc : item.imageSrc,
    price : item.price,
    title : item.title,
    num :1
    }
    })
    }
    this.setTabBar()
    await ml_showSuccess('Order placed successfully')
    }

    Step 7: Change the value at the top right corner of the navigation bar

    On the home page, when placing an order, call the wx.setTabBarBadge() method. The index property specifies the shopping cart page, and text specifies the value (string type). Obtain data from the shopping cart database and use the forEach() function to sum the num values of all products in the shopping cart database. If the cumulative num result is 0, directly return the function. If not zero, assign the result to text (explicitly converted to string type). Invoke the onTabItemTap() click event handler function. When the shopping cart is clicked, call the wx.setTabBarBadge() method and set text to an empty string, thereby hiding the value at the top right corner.

      // Update the value at the top right corner of the tabBar
    async setTabBar(){
    let total=0
    let res=await carts_col.get()

    res.data.forEach(v => {
    total += v.num
    })
    if(total === 0) return
    //console.log('123333333333')
    wx.setTabBarBadge({
    index: 1,
    text: text: total + '',//convert to string
    })
    }

    Build the Details Page

    This article primarily focuses on explaining the detail page detail.js. For more details on the detail page code, refer to detail.js configuration and frontend page detail.wxml.

    Step 1: Set up redirection

    Use the navigator navigation component in index.wxml to navigate to the product details page.

      <navigator hover-class='hcls' class='goods' url="/pages/detail/detail?id={{item._id}}">

    Step 2: Obtain Clicked Product Information

    Based on the product ID passed to the details page, obtain the detailed product information from the product database by calling wx.cloud.database().collection(), then call doc() to filter products by the passed ID.

    const db = wx.cloud.database()
    const goods_col = db.collection('goods')
    Page({
    data : {
    detail : {}
    },
    onLoad(options){
    let { id } =options
    console.log('id',id)
    this.loadDetailData(id)
    },
    // Load data details
    async loadDetailData(id){
    // Obtain the database product
    let ins = goods_col.doc(id)
    // Accumulated
    await ins.update({
    data: {
    count : db.command.inc(1)
    //log('123')
    }
    })
    // Obtain
    let res =await ins.get()
    // Assign
    this.setData({
    detail : res.data
    })
    }
    })

    Step 3: Modify Product Traffic

    Filter out the product by the ID passed from the home page, then call update to modify the value of count so that it increments by one each time it is accessed.

        // Accumulated
    await ins.update({
    data: {
    count : db.command.inc(1)
    //log('123')
    }
    })

    The following figure shows the effect.

    Building a Shopping Cart

    This article primarily focuses on the shopping cart cart.js. For more details on the shopping cart code, refer to cart.js Configuration and Frontend Page cart.wxml.

    Step 1: Load Shopping Cart List

    Call the wx.cloud.database().collection() method to access the cloud shopping cart database and display the data.

      async loadCartsData(){
    let res = await carts_col.get()
    console.log('carts' , res)
    this.setData({
    carts : res.data
    })
    this.setCart(res.data)//Count total
    },

    Step 2: Set Total Price and Quantity of Goods

    Pass the shopping cart data from the load shopping cart database function to the function that calculates the total price and total quantity of goods. Call the forEach() method to calculate the total price and total quantity of goods. The total price is obtained by traversing the elements in the shopping cart database and summing the product of each item's quantity and its unit price. The total quantity is obtained by summing the quantities of each item in the shopping cart database. Finally, use setData() to set the total price and total number of goods displayed on the shopping cart page.

      //Count total
    setCart(carts){
    let totalCount=0
    let totalPrice=0

    carts.forEach(v =>{
    totalCount += v.num
    totalPrice += v.num*v.price
    })

    this.setData({
    totalCount,
    totalPrice,
    })
    },

    Step 3: Modify Product Quantity

    By clicking the plus/minus buttons on the shopping cart page, the bindtap attribute triggers corresponding functions to add to cart or decrease cart items, passing the ID of the clicked product. In the function, filter the product in the shopping cart database by ID, then call the update() method to increment or decrement the num value of the specified product.

      // Increment
    async addCount(e){
    // Obtain id
    let id = e.currentTarget.dataset.id
    // Modify num value
    let res =await carts_col.doc(id).update({
    data:{
    num :db.command.inc(1)
    }
    })
    this.loadCartsData()
    await ml_showSuccess('Added successfully')
    },
    // Delete product
    async deleteCount(e){
    // Obtain product id
    let id = e.currentTarget.dataset.id
    // Modify num value
    let res =await carts_col.doc(id).update({
    data:{
    num :db.command.inc(-1)
    }
    })
    console.log('res ----',res)
    console.log('id-------',e.currentTarget.dataset.num)
    await ml_showSuccess('Deleted successfully')
    let num=await carts_col.doc(id).num
    console.log('the value of num', num)
    if( num === 0 )
    {
    console.log('product quantity is 0')
    }
    this.loadCartsData()
    },

    Effect as shown in the figure:

    At this point, all features of the mini program have been implemented. For more details, please refer to the sample code.