Recently, I was engaged in a small program competition. What's more, I briefly recorded the pit I stepped on during the development of learning small programs and the problem of high blood pressure. In addition, this document was recorded by me when I learned the new vision course at station b. If you need it, you can go to station b to have a look. This document closely follows the contents of the previous document and mainly describes how to configure nodejs installation in vant environment, some problems encountered, and how to solve and debug them.
Install plug-ins
Install nodejs configuration environment variables
Vant web app plugin
- Click to enter the official website
- Installation tutorial
1. Right click on the miniprogram to open cmd and enter the following command to install the plug-in
npm i @vant/weapp -S --production
2. Click Tools – build npm
Using the vant web app plug-in
- On app JSON or index Introducing components into JSON
"usingComponents": {
"van-button": "@vant/weapp/button/index"
}
//app.json "sitemapLocation": "sitemap.json", //Remember to delete v2 //"style": "v2", "usingComponents": { "van-button": "@vant/weapp/button/index" // ... Put the others here }
For example, click the like icon
//index.html <view class="out"> <view class="list"> <view class="row" wx:for="{{8}}" wx:key="index"> <navigator class="box" url="/pages/detail/detail"> <view class="pic"> <image class="img" mode="aspectFill" src="../../images/psmajor02.jpg2.jpg"/> </view> <view class="text"> <view class="title">Here is the title text, here is the title text, here is the title text, here is the title text, here is the title text, here is the title text, here is the title text, here is the title text</view> <view class="info"> <view><van-icon name="clock-o" />12-12</view> <view><van-icon name="eye-o"/>88</view> <view><van-icon name="good-job-o" /> 12</view> </view> </view> </navigator> </view> </view> </view>
//index.css .out .box .info{font-size: 28rpx; color:#888; display: flex; justify-content: space-between;} .out .box .info .van-icon{margin-right: 5rpx;}
CMS content model management
Configure cms
- Register cms, click more content management of cloud development platform, open and set account password
- Click the website to log in cms platform and enter the account password
- The created item id is a unique identifier and can be diy
- Content model - equivalent to creating a database table - single line string equivalent to column name
Obtain specified data through cloud function
Error reporting on Environment
Solution: configure the environment variable env in advance
- First, on app Configure env in JS
//app.js App({ onLaunch: function () { if (!wx.cloud) { console.error('Please use 2.2.3 Or more basic libraries to use cloud capabilities') } else { wx.cloud.init({ // env Parameter Description: // The env parameter determines which cloud environment resources will be requested by default for the next cloud development call (wx.cloud.xxx) initiated by the applet // Please fill in the environment ID here. You can open the cloud console to view the environment ID // If it is not filled in, the default environment (the first created environment) will be used // Look here env: 'bruan-cloud-8gr3l2csc1dd6dac', traceUser: true, }) } this.globalData = {} } })
- Specify env in cloud function
// Cloud function entry file const cloud = require('wx-server-sdk') cloud.init({ env:"bruan-cloud-8gr3l2csc1dd6dac" })
- Specify the environment variable env when calling callfusion on the page
getData(size=0){ wx.cloud.callFunction({ name:"artical_list_get", data:{ size:size, }, //crux config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' }, }).then(res=>console.log(res)) },
Render the data and add the loading style
- Index. In the index folder JS - getData part code is as follows
onLoad: function (options) { this.getData(0); }, //Write independently getData(size=0){ wx.cloud.callFunction({ name:"artical_list_get", data:{ size:size, }, config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' }, }).then(res=>{ console.log(res); this.setData({ listArr:res.result.data }) })
- Cloud function article_ list_ The get code is as follows
// Cloud function entry file const cloud = require('wx-server-sdk') cloud.init({ env:"bruan-cloud-8gr3l2csc1dd6dac" }) const db = cloud.database(); // Cloud function entry function exports.main = async (event, context) => { let size = event.size; // limit() limits the number of pages to seven // How many news items does skip() skip return await db.collection("article_list").orderBy("_createTime","desc") .limit(7) .skip(size) .get(); }
- Loading loading style
<view class="loading"> <van-loading type="spinner" color="#1989fa" > <view wx:if="true">Loading...</view> <view wx:if="">No more~</view> </van-loading> </view>
- app. Configuration items in JSON
"usingComponents": { "van-button": "@vant/weapp/button/index", "van-icon": "@vant/weapp/icon/index", "van-loading": "@vant/weapp/loading/index" }
Touch the bottom and load more loading styles
Bottom event handler
/** * Initial data of the page */ data: { listArr:[], }, getData(size=0){ wx.cloud.callFunction({ name:"artical_list_get", data:{ size:size, }, config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' }, }).then(res=>{ console.log(res); this.setData({ listArr:res.result.data }) }) }, /** * Handler for bottom pull event on page */ onReachBottom: function () { this.getData(this.data.listArr.length); },
At this time, the effective pull-down operation cannot be carried out, and faults will appear. It is necessary to overlay and connect the new and old data.
getData(size=0){ wx.cloud.callFunction({ name:"artical_list_get", data:{ size:size, }, config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' }, }).then(res=>{ //New and old data links let oldData = this.data.listArr; let newData = oldData.concat(res.result.data); console.log(res); this.setData({ listArr:newData }) }) },
The change of state when the bottom is loaded more, that is, more loads appear.. Or is the load complete
Solution: judge whether the length of the obtained array is less than 0 in getData, and make changes to the defined global variables
data: { listArr:[], //Global variable loading loading : "true", }, getData(size=0){ wx.cloud.callFunction({ name:"artical_list_get", data:{ size:size, }, config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' }, }).then(res=>{ if(res.result.data<=0){ this.setData({ loading:false, }) } let oldData = this.data.listArr; let newData = oldData.concat(res.result.data); console.log(res); this.setData({ listArr:newData }) }) },
The loading style of the front-end html interface needs to be judged
<view class="loading"> <van-loading type="spinner" color="#1989fa" > <view wx:if="{{loading}}">Loading...</view> <view wx:else="">No more~</view> </van-loading> </view>
util tool method modification timestamp
common.js common tool class code
module.exports={ //Quantity change value getNumber(num){ if(num<1000){ return num }else if(num>=1000 && num<10000){ let n =(num/1000).toFixed(1)+"k" return n }else if(num>=10000 && num<100000){ let n =(num/10000).toFixed(1)+"w" return n }else if(num>=100000){ return "10w+" }else{ return 0 } }, //Multifunctional time stamp format conversion method getTime(t,type=0){ let time = new Date(t); let year = time.getFullYear()+""; let month =time.getMonth()+1; month = month< 10 ? "0"+month:month+""; let day =time.getDate(); day = day<10 ? "0"+day:day+""; let hours=time.getHours(); hours = hours<10 ? "0"+hours :hours+""; let min = time.getMinutes(); min=min<10 ? "0"+min :min+""; let second = time.getSeconds(); second = second<10? "0"+second :second+""; let arr=[ `${year}-${month}-${day}`, `${year}year ${month}month ${day}day`, `${year}-${month}-${day} ${hours}:${min}:${second}`, `${year}year ${month}month ${day}day ${hours}Time ${min}branch ${second}second`, `${month}-${day}`, `${month}month ${day}day`, `${hours}:${min}:${second}`, `${hours}Time ${min}branch ${second}second`, ] return arr[type] } }
Introduction of tool classes
// miniprogram/pages/index/index.js import common from "../../util/common" Page({ /** * Initial data of the page */ data: { listArr:[], loading : "true", },
Or preprocess the data in getData
getData(size=0){ wx.cloud.callFunction({ name:"artical_list_get", data:{ size:size, }, config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' }, }).then(res=>{ // Modify the timestamp and format the number res.result.data.forEach(item=>{ let hits = item.hits?item.hits:0 item.hits = common.getNumber(hits) item._createTime=common.getTime(item._createTime,4) }) if(res.result.data<=0){ this.setData({ loading:false, }) } let oldData = this.data.listArr; let newData = oldData.concat(res.result.data); console.log(res); this.setData({ listArr:newData }) }) },
The list page jumps to the details page
How to take id and other information to realize interaction before and after
The code is shown in the figure
//id = is defined here_ The id is transferred to the js file, and the id is set as a global variable in js to save its value <navigator class="box" url="/pages/detail/detail?id={{item._id}}"> <view class="pic"> <image class="img" mode="aspectFill" src="{{item.picture}}"/> </view> <view class="text"> <view class="title">{{item.title}}</view> <view class="info"> <view><van-icon name="clock-o" />{{item._createTime}}</view> <view wx:if="{{item.hits}}"><van-icon name="eye-o"/>{{item.hits}}</view> <view><van-icon name="good-job-o" /> 12</view> </view> </view> </navigator>
// detail.js let id; Page({ //Fetch data when page is loaded /** * Life cycle function -- listening for page loading */ onLoad: function (options) { id = options.id; console.log(id); this.getDetail(); }, /** * Initial data of the page */ data: { detail:{} }, getDetail(){ wx.cloud.callFunction({ name:"article_list_get_one", data:{ id:id } }).then(res=>{ console.log(res); this.setData(res=>{ this.setData({ detail:res.result.data }) }) }) },
//Cloud function // Cloud function entry file const cloud = require('wx-server-sdk') cloud.init({ env:"bruan-cloud-8gr3l2csc1dd6dac" }) const db = cloud.database(); // Cloud function entry function exports.main = async (event, context) => { let id = event.id; return await db.collection("article_list").doc(id).get() }
Rich text editor for format conversion with rich text
<rich-text nodes="{{detail.content}}"></rich-text>
Use regular expressions to modify images within rich text
Incomplete image display
getDetail(){ wx.cloud.callFunction({ name:"article_list_get_one", data:{ id:id } }).then(res=>{ console.log(res); // Replace with regular expressions res.result.data.content= res.result.data.content.replace(/<img /,"<img style='max-width:100%'") this.setData({ detail:res.result.data }) }) },
Syntax of wxs
Transfer the commonly used tool files in util to the newly built wxs folder
es6 format cannot be used
++To use: Fun
var cannot use let
Date() --> getDate(t)++
module.exports={ //Quantity change value getNumber:function(num){ if(num<1000){ return num }else if(num>=1000 && num<10000){ var n =(num/1000).toFixed(1)+"k" return n }else if(num>=10000 && num<100000){ var n =(num/10000).toFixed(1)+"w" return n }else if(num>=100000){ return "10w+" }else{ return 0 } }, } //Multifunctional time stamp format conversion method getTime:function(t,type=0){ var time = getDate(t); var year = time.getFullYear()+""; var month =time.getMonth()+1; month = month< 10 ? 0+month:month+""; var day =time.getDate(); day = day<10 ? 0+day:day+""; var hours=time.getHours(); hours = hours<10 ? 0+hours :hours+""; var min = time.getMinutes(); min=min<10 ? 0+min :min+""; var second = time.getSeconds(); second = second<10? 0+second :second+""; var arr=[ year+"-"+month+"-"+day, year+"-"+month+"-"+day+" "+hours+":"+min+":"+second, ] return arr[type] }
User authorization and its use
// Click the like button clickLike(){ //getUserInfo has been disabled wx.getUserProfile({ desc: 'Authorization needs', success:res=>{ console.log(res); //Deconstruction of res object let {avatarUrl,nickName}=res.userInfo let posttime=Date.now(); //id is an inherent global variable console.log(nickName,avatarUrl,posttime,id); } }) },
cache
Save user information with cache, so you don't have to set so many variables
// Click the like button clickLike(){ wx.getUserProfile({ desc: 'Authorization needs', success:res=>{ wx.setStorageSync('userInfo', res.userInfo) } }) },
Store user information in app JS
You need to declare the app object in the file and call the method
//Define app object const app = getApp(); Page({ // Click the like button clickLike(){ wx.getUserProfile({ desc: 'Authorization needs', success:res=>{ //Caching mechanism wx.setStorageSync('userInfo', res.userInfo) //Stored in global variables //As soon as setStorageSync refreshes, the data will be lost app.globalData.userInfo=res.userInfo } }) },
Global function to determine whether the user logs in
//app.js App({ onLaunch: function () { if (!wx.cloud) { console.error('Please use 2.2.3 Or more basic libraries to use cloud capabilities') } else { wx.cloud.init({ // env Parameter Description: // The env parameter determines which cloud environment resources will be requested by default for the next cloud development call (wx.cloud.xxx) initiated by the applet // Please fill in the environment ID here. You can open the cloud console to view the environment ID // If it is not filled in, the default environment (the first created environment) will be used env: 'bruan-cloud-8gr3l2csc1dd6dac', traceUser: true, }) } this.globalData = {} }, hasUserInfo(){ //If you don't have this at first, go directly to the next step if(this.globalData.userInfo && this.globalData.userInfo.nickName){ return true; } //Determine whether there are records in the cache let userInfo = wx.getStorageSync('userInfo'); //If so, assign the cache to the global variable if(userInfo&&userInfo.nickName){ //Reassign once this.globalData.userInfo = userInfo; //Return true return true; }else{ return false; } }, })
detail.js
// pages/detail/detail.js let id; const app = getApp(); Page({ /** * Initial data of the page */ data: { detail:{} }, // Click the like button clickLike(){ if(app.hasUserInfo()){ console.log("You can like it"); }else{ wx.getUserProfile({ desc: 'Authorization needs', success:res=>{ wx.setStorageSync('userInfo', res.userInfo) app.globalData.userInfo=res.userInfo } }) } }, //Send to database pushData(){ let posttime=Date.now(); wx.cloud.callFunction({ data:{ nickName, avatarUrl, posttime, artid:id }, name:"article_liske_add" }) }, // Get detailed data getDetail(){ wx.cloud.callFunction({ name:"article_list_get_one", data:{ id:id } }).then(res=>{ console.log(res); res.result.data.content= res.result.data.content.replace(/<img /,"<img style='max-width:100%'") this.setData({ detail:res.result.data }) }) }, /** * Life cycle function -- listening for page loading */ onLoad: function (options) { id = options.id; console.log(id); this.getDetail(); }, }
Send to database
Cloud function
// Cloud function entry file const cloud = require('wx-server-sdk') cloud.init({ env:"bruan-cloud-8gr3l2csc1dd6dac" }) const db = cloud.database(); // Cloud function entry function exports.main = async (event, context) => { //Receive the openid of the current user const openid = cloud.getWXContext().OPENID //d deconstruct the incoming object let {nickName,avatarUrl,posttime,artid}=event; //Write to database return await db.collection("article_like").add({ data:{ nickName,avatarUrl,posttime,artid,openid } }) }
detail.js
//Send to database pushData(){ let posttime=Date.now(); wx.cloud.callFunction({ name:"article_like_add", data:{ nickName:app.globalData.userInfo.nickName, avatarUrl:app.globalData.userInfo.avatarUrl, posttime, artid:id }, config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' }, }) },
Get the number of likes of real users
<wxs module="public" src="../../wxs/public.wxs"></wxs> <view class="detail"> <view class="title">{{detail.title}}</view> <view class="content"> <rich-text nodes="{{detail.content}}"></rich-text> </view> <view class="info"> <view class="row">Author:{{detail.author}}</view> <view class="row">Published on:{{public.getTime(detail._createTime,1)}}</view> <view class="row" wx:if="{{detail.hits}}">Hits:{{public.getNumber(detail.hits)}}</view> </view> <view class="recommend active" bindtap="clickLike"> <view class="icon"><van-icon name="good-job" /></view> <--! Number of likes > <view class="num">{{detail.zanSize}}</view> </view> <view class="userinfo"> <view class="text">- Like users -</view> <view class="picgroup"> <image wx:for="{{6}}" wx:key="index" src="../../images/2019_ps.jpg" mode="aspectFill"></image> </view> </view> </view>
articl_ list_ get_ Index of one cloud function JS file
// Cloud function entry file const cloud = require('wx-server-sdk') cloud.init({ env:"bruan-cloud-8gr3l2csc1dd6dac" }) const db = cloud.database(); // Cloud function entry function exports.main = async (event, context) => { let id = event.id; let res1 = await db.collection("article_list").doc(id).get(); //Find the number of likes by id comparison let res2 = await db.collection("article_like").where({ artid:id }).count(); res1.data.zanSize = res2.total; return res1; }
Update the avatar of likes, and users who like can highlight it
To save resources, you can use the field function for mapping
Click me to view the field document
Sample code
Only description, done and progress fields are returned:
db.collection('todos').field({ description: true, done: true, progress: true, }) .get() .then(console.log) .catch(console.error)
articl_list_get_one file
// Cloud function entry file const cloud = require('wx-server-sdk') cloud.init({ env:"bruan-cloud-8gr3l2csc1dd6dac" }) const db = cloud.database(); // Cloud function entry function exports.main = async (event, context) => { let openid = cloud.getWXContext().OPENID; let id = event.id; let res1 = await db.collection("article_list").doc(id).get(); //Find the number of likes by id comparison let res2 = await db.collection("article_like").where({ artid:id }).count(); //Get likes user Avatar let res3 = await db.collection("article_like").where({ artid:id }).field({ avatarUrl:true }).orderBy("posttime","desc").limit(5).get(); //Judge whether it has been liked let res4 = await db.collection("article_like").where({ openid:openid, artid:id }).count(); if(res4.total){ res1.data.onlike = true }else{ res1.data.onlike = false } res1.data.zanSize = res2.total; res1.data.userArr = res3.data.reverse(); return res1; }
<wxs module="public" src="../../wxs/public.wxs"></wxs> <view class="detail"> <view class="title">{{detail.title}}</view> <view class="content"> <rich-text nodes="{{detail.content}}"></rich-text> </view> <view class="info"> <view class="row">Author:{{detail.author}}</view> <view class="row">Published on:{{public.getTime(detail._createTime,1)}}</view> <view class="row" wx:if="{{detail.hits}}">Hits:{{public.getNumber(detail.hits)}}</view> </view> <view class="recommend {{detail.onlike? '':'active'}}" bindtap="clickLike"> <view class="icon"><van-icon name="good-job" /></view> <view class="num">{{detail.zanSize}}</view> </view> <view class="userinfo"> <view class="text">- Like users -</view> <view class="picgroup"> <image wx:for="{{detail.userArr}}" wx:key="index" src="{{item.avatarUrl}}" mode="aspectFill"></image> </view> </view> </view>
Changes in avatars, cancelled changes, numbers, etc
Likes in detail file
//Send to database pushData(){ let onlike = this.data.detail.onlike; let zanSize = this.data.detail.zanSize; let userArr = this.data.detail.userArr; if(onlike){ zanSize-- userArr.forEach((item,index)=>{ if(item.avatarUrl==app.globalData.userInfo.avatarUrl){ // He had his head removed userArr.splice(index,1) } }) }else{ zanSize++ userArr.push({avatarUrl:app.globalData.userInfo.avatarUrl}) // Intercept the first 5 if(userArr.length>=5){ userArr=userArr.slice(1,6) } } //Dynamic update this.setData({ "detail.onlike":!onlike, "detail.zanSize":zanSize, "detail.userArr":userArr, }) //Incoming database let posttime=Date.now(); wx.cloud.callFunction({ name:"article_like_add", data:{ nickName:app.globalData.userInfo.nickName, avatarUrl:app.globalData.userInfo.avatarUrl, posttime, //Pass the article id into the artid in the likes table artid:id }, config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' }, }) },
Beautify the loading effect of UI interface skeleton screen
<wxs module="public" src="../../wxs/public.wxs"></wxs> <view class="detail"> <van-skeleton title row="8" loading="{{loading}}"> <view class="title">{{detail.title}}</view> <view class="content"> <rich-text nodes="{{detail.content}}"></rich-text> </view> <view class="info"> <view class="row">Author:{{detail.author}}</view> <view class="row">Published on:{{public.getTime(detail._createTime,1)}}</view> <view class="row" wx:if="{{detail.hits}}">Hits:{{public.getNumber(detail.hits)}}</view> </view> <view class="recommend {{detail.onlike? '':'active'}}" bindtap="clickLike"> <view class="icon"><van-icon name="good-job" /></view> <view class="num">{{detail.zanSize}}</view> </view> <view class="userinfo" > <view class="text">- Like users -</view> <view class="picgroup"> <image wx:for="{{detail.userArr}}" wx:key="index" src="{{item.avatarUrl}}" mode="aspectFill"></image> </view> </view> </van-skeleton> </view>