Skip to main content

Store WeChat Mini Program Development Practice

Overview

This article takes a mall mini-program development project as an example, introducing the preparatory work in the WeChat mini-program development project process, the creation process of the mini-program, the functions of various files in the directory, and the cloud development functions to be used during development, such as cloud storage, cloud database, and cloud functions.

Note

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

Preparations

  1. Register Tencent Cloud.
  2. Enabled CloudBase for the mini program. For details, see Quick Start for WeChat Mini Program.

Operation Procedure

The specific operation procedure can be divided into the following 4 steps. For more details, refer to the sample.

Project Directory

FileDescription
Configuration file .json
  • Project configuration file `app.json`: used to configure page paths, set window and bottom navigation bar.
  • Page configuration files such as `index.json`: used to implement personalized settings for their respective pages.
  • Template file .wxmlCommonly used page template files such as `index.wxml` are similar to HTML, employing tag-based languages 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 files such as `index.wxss`: used to configure personalized styles for the page, which can override global styles within their respective pages.
  • Logic file .jsLogic files are used to implement the business logic functionality of pages, such as data retrieval, condition judgment, and page prompts, all achieved by writing methods within these files.

    Environment Configuration

    This article primarily focuses on the project configuration files app.json and app.js. For more detailed code implementation of project configuration files, refer to app.json Configuration and app.js Configuration.

    Step 1: Create Project Pages

    First, perform requirement analysis:

    • An e-commerce site requires at least one homepage to display its products to users.
    • A product detail page is used to present information about individual items.
    • A shopping cart is used for users to store their desired items.

    Therefore, we need to configure the pages array in the mini-program project configuration file app.json. After entering the corresponding paths, the developer tools will automatically generate the page files at the specified paths.

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

    Step 2: Configure the Mall'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 mall consists of two main sections - the homepage and shopping cart - add two buttons to the tabBar's list property, configuring their page paths, titles, and icons.

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

    Effect diagram as shown below:

    Step 3: Configure the CloudBase Environment

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

    2. In app.js, call the API by passing the cloud 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: "xxxxx", // Enter your environment ID
    });
    },
    globalData: {
    userInfo: null,
    },
    });

    Step 4: Create Database

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

    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 of each data record are as follows:

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

    Product images must be imported into cloud storage first to generate their locations, 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. Enter 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 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 creation result is shown in the following figure:

    Building the Mall Homepage

    This article primarily focuses on the mall homepage's index.js and index.wxml. For more details on the project configuration file code, refer to index.js configuration and frontend page index.wxml.

    Mall homepage effect diagram as shown below:

    Step 1: Access Cloud Database

    In the mall page's index.js, call wx.cloud.database().collection() to get a reference to the product database in the current cloud development environment.

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

    When errors frequently occur during database access or when modifying data in the console, it is generally due to cloud database permission issues. Setting all permissions to true in the custom rule permissions can resolve such errors.

    Step 2: Load Product List Data

    In the homepage's index.js, write the logic for loading the product data list, set the loading animation to be hidden, configure the number of products displayed at once in the list, and 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],// Append and merge with existing data
    _page: ++_page,
    hasmore : res.data.length === LIMIT
    })
    },

    Code Explanation

    • res: Variable that stores the return value of the product database query.
    • limit(): Limits the number of products displayed at once.
    • LIMIT: The initial value is 5.
    • _page: Initially 0, incremented by one in subsequent iterations.
    • _page*LIMIT: Indicates skipping a specified number of elements in the database before starting to fetch data.
    • setData(): Concatenates the product data retrieved each time.

    Step 3: Set up pull-up event to load product data

    First, limit the quantity of data retrieved per load in the data loading function, which can be defined as accessing five product records from the cloud at a 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({
    No more data available
    icon : "none"
    })*/
    ml_showToast('No more data available')
    return console.log('No more data')
    }
    console.log('Pull-up refresh')
    this.loadListData()
    },
    Note

    Since only five records are loaded per request in the data loading function, it is necessary to concatenate the previously loaded data with the data retrieved in the current function call using setData at the end of the function. This ensures users can still view earlier product data when scrolling down.

    Step 4: Configure product loading completion notification

    1. Set a bool variable with an initial value of true. In the data loading function, check whether the amount of data obtained from the database is less than the set fetch limit. If less, it indicates that the data in the database has been fully loaded, then set the bool variable to false; otherwise, the loading is not complete.
    2. Then, in the pull-up event handler, set up a listener at the beginning. When the bool variable is detected as false, call wx.showToast() to indicate no more data is available for loading, and directly return from the pull-up loading function.
    Note

    Since wx.showToast() can be invoked in multiple scenarios, it is encapsulated for reuse. Simply import it on required pages to call directly.

    Step 5: Configure the pull-down event for page refresh

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

    Step 6: Register the order placement click event

    On the mall homepage's order button, use the catchtap attribute to set up the function for adding items to the shopping cart.

    Warning

    The bindtap attribute cannot be used here because it would cause event bubbling and navigate to the product details page upon clicking. Whereas catchtap prevents redirection and directly triggers the function to add items to the shopping cart, then passes the clicked product data from the homepage to the cart page.

    To implement the add-to-cart functionality, it's necessary to check whether the product to be ordered already exists in the shopping cart. Retrieve data from the cart database using the ID passed from the homepage order placement:

    • A successful retrieval indicates that the product is already in the shopping cart. Then call update() to increment num by one, and call the encapsulated wx.showToast() to show a message that the product has already been added.
    • If the retrieval fails, it indicates that the product has not been added to the shopping cart. The product data must then be added to the shopping cart database by calling add() to add the product data to the shopping cart database. 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 indicate the successful operation. The code implementation is as follows:

    Add to Cart
    async addCart(e){
    // Get products
    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('Value exists', res)
    // Value exists
    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: Update the value in the top-right corner of the navigation bar

    When placing an order on the home page, call the wx.setTabBarBadge() method. The index property specifies the shopping cart page, and text specifies the value (string type). Retrieve data from the shopping cart database, then call the forEach() function to sum the num values of products in the cart. If the accumulated num result is 0, return directly. Otherwise, assign the result to text (converted to string type). Call the click-triggered event handler onTabItemTap(). When the shopping cart is clicked, call wx.setTabBarBadge() and assign an empty string to text, thereby hiding the value in the top-right corner.

      // Update the value in the top-right corner of the tebbar
    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: total + '', // Convert to string
    })
    }

    Set up details page

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

    Step 1: Set up redirect

    In index.wxml, use the navigator component to navigate to the product details page.

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

    Step 2: Retrieve Clicked Product Information

    Based on the product ID passed to the details page, retrieve the detailed product information from the product database by calling wx.cloud.database().collection(), then call doc() and filter the product by passing the 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){
    // Retrieve product from the database
    let ins = goods_col.doc(id)
    // Total
    await ins.update({
    data: {
    count : db.command.inc(1)
    //log('123')
    }
    })
    // Get
    let res =await ins.get()
    // Assign
    this.setData({
    detail : res.data
    })
    }
    })

    Step 3: Modify product view count

    Filter the product by the ID passed from the homepage, then call update to modify the count value, incrementing it by one each time it is accessed.

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

    The following figure shows the effect.

    Building a Shopping Cart

    This article focuses on the shopping cart's 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 Products

    Pass the cart data from the load cart database function to the function that calculates the total price and total quantity of products, and call the forEach() method to compute the total price and total quantity. The total price is obtained by traversing the elements in the cart database and summing the product of each item's quantity and unit price. The total quantity is obtained by summing the quantity of each item in the cart database. Finally, use setData() to set the total price and total number of products displayed on the 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, call the bindtap attribute to trigger the corresponding functions for adding or reducing items in the cart. Pass the ID of the clicked product, then filter the product in the cart database by ID within the function, and finally call the update() method to increment or decrement the num value of the specified product.

      // Increment
    async addCount(e){
    // Get id
    let id = e.currentTarget.dataset.id
    // Update num quantity
    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){
    // Get product id
    let id = e.currentTarget.dataset.id
    // Update num quantity
    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('num value', 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, refer to the sample code.