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.
The source code materials involved in this example tutorial have all been properly authorized.
Preparations
- Register Tencent Cloud.
- 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
File | Description |
---|---|
Configuration file .json | |
Template file .wxml | Commonly 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 | |
Logic file .js | Logic 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
Go to the WeChat Developer Tools > Cloud Development Console page and copy the Environment ID.
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.
Go to the WeChat Developer Tools > Cloud Development Console > Database page. Create three collections: carts, goods, and orders.
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.
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
Go to the WeChat Developer Tools > Cloud Development Console > Storage page.
Click New Folder and name it goods.
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
Create a folder named cloudfunction for cloud functions in the directory, then set the cloudfunctionRoot property to "cloudfunction/" in project.config.json.
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')
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()
},
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
- 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.
- 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.
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
- 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')
},
- 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.
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.