Small program cloud development likes case implementation and environment vant plug-in configuration

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

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>

Keywords: Javascript Front-end Mini Program

Added by tobykw13 on Sun, 27 Feb 2022 10:32:03 +0200