I have learned about the technical stack and framework related to wechat small program development very early, and I have applied for the account of small program. However, the demo project that I wrote has not been released to the small program. The main reason for this is that it is not worth publishing, plus various audit related. And this preparation to write a search related small procedures, is also the time to combat the release, along with the record of the entire development and release process.

Online experience: Scan the qr code of the small program below

Small program source address: github.com/kuizuo/ques…

Technology stack

The small program uses Taro + Vue3 + NutUI. The reason why I choose this technology stack is mainly to use Vue3, while UNIApp’s support for Vue3 is not friendly, as I also explained in my last article, there are only a few Vue3 that support UniApp. So this set of technology stack is selected for development.

Page design

Project configuration

Project structures,

Installation and use | Taro document (jd.com)

taro init myApp
Copy the code

Configuration is as follows

After installing dependencies, use NPM Run Dev: Downloadp to download projects.

Axios encapsulation

The most used library for HTTP requests on the Web side is AXIos, but using axios in an applet will prompt you that adapter is not defined because the applet cannot parse fields such as browser Module in package.json.

To use AxiOS, you can install either the Axios-MiniProgram or the taro-Axios library (I chose the latter, but the former is 5KB smaller), which is an Adapter for AxiOS with applets, introduced and used not that different from Axios. Here’s the code I wrapped

import axios from 'taro-axios'
import Taro from '@tarojs/taro'
import { useAuthStore } from '@/stores/modules/auth'

const showErrorToast = (msg) = > {
  Taro.showToast({
    title: msg,
    icon: 'none'})},const instance = axios.create({
  baseURL: process.env.BASE_URL,
})

instance.interceptors.request.use(
  (config) = > {
    Taro.showLoading({
      title: 'Loading'.mask: true,})let token = Taro.getStorageSync('token')
    if (typeof token == 'undefined') {
      token = ' '
    }
    config.headers = {
      'Content-Type': 'application/json; charset=utf-8'.Authorization: token,
    }
    return config
  },
  (error) = > {
    console.log(error)
    return Promise.reject(error)
  },
)

// Respone interceptor
instance.interceptors.response.use(
  (response: any) = > {
    Taro.hideLoading()
    if (response.data.isError) {
      showErrorToast(response.data.error.message)
    } else {
      return response
    }
  },
  (error) = > {
    if (error.response) {
      Taro.hideLoading()
      console.log('err', error)

      let res = error.response.data
      switch (res.code) {
        case 400:
          showErrorToast(res.message || 'Illegal request')
          break
        case 401:
          const authStore = useAuthStore()
          authStore.login()
          / / showErrorToast (res) message | | 'current login has expired, please log in again)
          // Taro.navigateTo({
          // url: '/pages/login/index'
          // })
          break
        case 403:
          showErrorToast(res.message || 'Illegal request')
          break
        case 404:
          showErrorToast(res.message || 'Requested resource not found')
          break
        case 500:
        case 502:
          showErrorToast(res.message || 'The server is off.')
          break
        default:
          showErrorToast(res.message || res.statusText)
      }
    } else {
      console.log(error)
      showErrorToast('Please check network connection status')}return Promise.reject(error)
  },
)

export default instance
Copy the code

Nothing to say, and the web side basically the same. Wx Loading and Toast were added. Then, when the token expires, I should jump to the login page, but I did not write the login page, but called login again to achieve the effect of silent login.

Get unique User Id (OpenID)

With the help of wechat small program can be very convenient to get wechat users. In wechat, in order to identify users, each user will generate a secure OpenID for each public account or small program and other applications. Developers can identify users by this id.

There are several ways to obtain OpenID (in this case, Taro). The code can be found in the official wX documentation.

Taro. Login (option) | Taro document (jd.com)

First call taro.login () to get a 5-minute code, then get the openID code from api.weixin.qq.com as follows

Taro.login({
  success(res) {
    let code = res.code
    let appId = 'Applet -> Development Management -> Development Settings -> Developer ID Get'
    let appSecret = 'Applet -> Development Management -> Development Settings -> Developer ID Get'
    Taro.request({
      url: 'https://api.weixin.qq.com/sns/jscode2session'.data: {
        appid: appId,
        secret: appSecret,
        js_code: res.code,
        grant_type: 'authorization_code',},method: 'GET'.success(res) {
        console.log('openid', res.data.openid) / / get the openid
        console.log('session_key', res.data.session_key) / / get session_key}})}})Copy the code

But now the small program is unable to add api.weixin.qq.com domain name, so the above scheme in the small program end is invalid, can only be transferred to the back end. Small program official has a practice chart

The entire steps

1. Call wx.login to get the code, or wx.getUserInfo to get the user data (nickname, avatar).

2. Since the background authorized domain name of the small program cannot authorize the domain name of wechat, it is necessary to pass the code and user data to its own server.

3. The server background receives the code and obtains the login status information (openID and session_key) from wechat API service with appID + AppSecret +code. The server encapsulates these login status information. For example, the tokens of session or JWT can be returned to the applet

4. When receiving the token, the applet saves it to the local storage (wx.setStorage) and sends the request to the server with the token each time.

However, if the use of cloud development can be removed from a lot of authentication related, but because of the database storage related, so I am using a self-built background server, and the back-end is not open source, so the specific logic code is not demonstrated (mainly considering security), write back-end login interface.

Obtaining mobile phone Number

Note: only enterprise applets can obtain the user’s mobile phone number, personal applets have no way to obtain.

In this article with instructions on how to get five lines of code get small application user phone number | WeChat open community (qq.com)

Get a phone number | WeChat open document (qq.com)

So there is no further (because I must be a personal account).

Obtaining User information

To get user information, you need to call getUserProfile, as shown below

Taro.getUserProfile({
    desc: 'Access to user personal Information'.success: function(res) {
    const userInfo = res.userInfo
    console.log(res.userInfo)
    }
}
Copy the code

It is important to note that getUserProfile must be triggered by a button, not by a life-cycle authorization window that the user can accept or reject. To put it bluntly, developers cannot obtain user information without the user’s knowledge (regarding user privacy).

There is also a small pit where getUserInfo gets the wechat user with a gray avatar

GetUserInfo cannot get the correct user information because the applets have modified the interface. Details can see Small program interface to adjust login, user information related to explain | WeChat open community (qq.com)

A normal login process:

Normally, you want to provide a dedicated login page, even if the login page has only one button, called one-click Login. Then the user clicks to trigger getUserProfile to obtain the user information. If the user refuses, the software is not allowed to be used. If the user permits, the software will enter the home page, and then the user information will be saved on the server, so that the next time the user visits, the user does not need to call getUserProfile interface again, directly from the server.

My approach is relatively rough. I directly allow the user to enter the home page, but when he uses the search function, he will judge whether the server has the user’s information. If not, he will call getUserProfile, and the authorization box will pop up for the user to choose. At the same time, checkSession is used to check whether the session has expired on the home page. If the session has expired, wx.login is invoked to update the login state. (However, if the back end does not determine whether the user information is complete, there is a way to bypass this approach to call the interface.)

Database setup

In fact, the main dependence of this small program is the database, and this database and the traditional relational type (Mysql) and document type (MongoDB) different, to do the search engine type search. For example, search “Li Bai”, you can get [Li Bai’s poetic style is] [Li Bai’s name] about The words of Li Bai, and request the speed of return. The two databases mentioned above are not easy to implement. If tens of millions of databases are involved, they will respond in seconds or even tens of seconds.

The database I chose is Elasticsearch, which is easy to implement and has a very objective response speed. (The specific implementation of their own understanding, back-end code is not considered open source)

Upload issued

When the local development is completed, click upload in the upper right corner, fill in the version number and project remarks, and upload successfully as shown in the picture below

You can see the code you just uploaded in the development version under version control

After clicking submit for review, you will be prompted to ensure that the project is not a beta or Demo (otherwise you will be punished accordingly) as shown below

The beta

Or select the experience version (only the account of the administrator and experiencer can access it) and scan the QR code of the experience version to access the project through wechat.

Review version

If you want to release the official version, you need to fill in the form below, and then wait 1-7 days (you can choose urgent, once a year).

Wait for the completion of the audit, test within one day, the audit version is as follows

The online version

Finally submitted for release, the online version is below

At this point, users can open wechat and access the app through small programs.

About the name

Maybe some people (this is me) are worried about whether they can change their name during the process of launching a small program.

First, it can be renamed. The APPID is the APPID, not a name. However, the name change will directly affect the user’s cognition of small program, thus affecting the loss of small program users. At the same time, the name change requirements are very strict, will search whether there is a similar small program, and whether there is a trademark certificate, and so on, and can only change the name twice a year, so the name and name change should be careful.

Some development considerations (pit)

Request: Fail URL not in domain list

One of the most annoying things about browsers is cross-domain, and this is not a problem for applets, but applets are even more demanding, and even if the back end allows cross-domain, applets request will prompt the error shown in the header. At this time, it is generally done as follows.

Network | WeChat open document (qq.com)

Ensure that the domain name is HTTPS. In addition, to facilitate debugging during development, it is generally selected in the local Settings and the valid domain name option is not validated, as shown below

In this case, devServer.proxy can be set up in config/index.js to send request correlation normally.

However, in the build environment, you need to configure the server domain name in the development management of the small program

Click “Start configuration” and the following configuration will be displayed after scanning the code

This is the domain name to request resources in the production environment, and HTTPS must be enabled.

After setting, restart the wechat developer tool or refresh the project configuration. Here, you need to log in using the AppID of the small program account, and the test number is invalid. Then the project configuration will set the legitimate domain name of Request, and the request can be normally responded to again.

Pinia persistence

Pinia has a plugin called pinia-plugin-persist that can persist store states. SessionStorage is not defined. The reason is that there is no sessionStorage and localStorag in the applet. So you still have to use the native data caching methods (getStorage, setStorage), or store the data to the back end.

Third-party components modify styles

In VUe3, to change a component style in a third-party component library, you need to use :deep(CSS selector), and generally add style scoped, but if you use it in an applet, you will find that the sub-component does not work, but when compiled to H5 it does. In this issue taro 3.0 + Vue scoped works in H5 and found a solution in wechat applet that does not work

Scoped generates **[data-v-xxx]** attributes in H5 mode, but not in applets, so using scopd is useless in applets. You can use cssModules if you add support for cssModules in config/index.js, as mentioned in issues above, and that’s it.

Then add module to style to work, without using :deep.

invalid code, rid: 6249d588-48af462b-xxxxxxx

If this error is displayed when the server obtains the OpenID from the API of the small program with the code obtained by wx.login, it is highly likely that there is something wrong with the APPID. The test number is used or the wrong APPID is filled in.

conclusion

Due to the small program (H5 mobile terminal) application to write less, so the page layout is convenient to write relatively simple, but there is no special general difference between the essence and front-end development, can not be customized some related tags and API, encountered in the reference.

But compared with the traditional Web development, the website only needs to have a public network server to access without audit, and the small program must be audited before it can be published, and there is a strict audit of the small program name. The main convenience lies in the acquisition of wechat users, while providing a complete development and deployment environment (developer tools, cloud development), plus user data analysis and so on.

My advice after Posting and writing this article is:

Uploading applets for others to access is not recommended unless necessary, especially for individual developers, the Web version may be a better choice.

Taro’s experience with Vue3 is much better than Uniapp’s (at least for now, personally). Uniapp relies too much on its own Hbuilder, but currently Taro’s Vue3 cannot be compiled into Android (React Native). So when it comes to android versus applets, Uniapp is a bit better than H5. However, if I only write small programs, I will not hesitate to use Taro.