“Get all the common functions of blog applets in one go” with applets · Cloud development
This article introduces how to realize the function button of the detail page of mini blog mini program, including comment, like, favorite and poster function specifically, here records the whole implementation process and some pits in the actual code.
Comments, likes, favorites function
Implementation approach
Implementation, the function of some articles, the main or comment, it is the bridge of communication between authors and readers, the comment function of derivative is nothing more than refinement of the interaction between the writer and the reader, or increase the spread of the article, when begin development so need to think about what you expect to achieve function, and the corresponding functions are realized.
My general rule of thumb is to go through the required features and general flow in my head, and then sketch a “very basic prototype, equivalent to the character of the product” in my notes.
Then I directly started to build the page and simple interaction “use fake data, finish the page first”. In fact, when constructing the page, I could supplement some defects in the process of the initial idea, so that I could make up for them in the design of the back-end and database structure, and the whole thing was basically perfect.
Looking back at the requirements of my small program, the first must be operation, at the bottom of the article needs to have an operation bar, used to send comments and other operations, after referring to some of the same type of small program, gradually realize their own set of style, style screenshots are as follows:
Once the feature is in place, the comment data needs to have a place to display “usually at the bottom of the post”, and then you have a list of comments at the bottom of the post, like this:
Since there is a “like” and “favorites” function button, does the user need to see the list of articles I “like” and “favorites”, so there is a corresponding list in “my”, the style is as follows:
So far, the most basic functions are almost the same, and then it depends on whether the back end can support these pages. “The main thing is to save and display data.”
For comments, there is definitely a need for a collection to hold user comments, and for user likes and favorites.
So based on the page we can design mini_comments and mini_posts_related collections. The former is used to save comment data, while the latter users save associations between user actions and articles.
The rest of the job is to realize, is nothing more than page interaction and data add, delete, change and check.
Detail point analysis
About the number of comments
There is currently a totalComments attribute in the collection of articles, which is incremented by 1 each time a comment is added to the article.
When I first wrote this, I checked it first and then updated it in two paragraphs. The original code is as follows:
let count=post.totalComments+1;
let result =await db.collection('mini_posts').doc(event.commentContent.postId).update({
data: {
totalComments: count
}
});
Copy the code
When I look at the documentation, I find that db.command. Inc can be used to add 1 to the original field without having to look it up again, and still maintain atomicity. The code is as follows:
const _ = db.command
let result = db.collection('mini_posts').doc(event.commentContent.postId).update({
data: {
totalComments: _.inc(1)
}
});
Copy the code
About adding sub-comments
Need to implement a reply under a comment.
In the interaction, when you click the commenter’s nickname or avatar, the corresponding click event will be triggered, in which the corresponding comment ID and necessary data will be recorded, and the focus will be set in the comment box:
/** * Click on the comment to reply */ focusComment:function (e) {
let that = this;
let name = e.currentTarget.dataset.name;
let commentId = e.currentTarget.dataset.id;
let openId = e.currentTarget.dataset.openid;
that.setData({
commentId: commentId,
placeholder: "Reply" + name + ":",
focus: true,
toName: name,
toOpenId: openId
});
},
Copy the code
Db.com mand. Push can be used to operate “update instruction, add one or more values to the end of an array of values for a field” when adding sub-comments in cloud development, and add:
/** * Add child comment * @param {} event */ asyncfunction addPostChildComment(event) {
let task = db.collection('mini_posts').doc(event.postId).update({
data: {
totalComments: _.inc(1)
}
});
await db.collection('mini_comments').doc(event.id).update({
data: {
childComment: _.push(event.comments)
}
})
await task;
}
Copy the code
About judging whether it has been collected
When the article is loaded for the first time, we need to determine whether the user has related operations on the article. If there are corresponding favorites and likes, the corresponding function ICONS need to be updated during initialization. The core code is as follows:
/** * Get favorites and likes */ getPostRelated: asyncfunction (blogId) {
let where = {
postId: blogId,
openId: app.globalData.openid
}
let postRelated = await api.getPostRelated(where, 1);
let that = this;
for (var item of postRelated.data) {
if (config.postRelatedType.COLLECTION === item.type) {
that.setData({
collection: { status: true, text: "Collected", icon: "favorfill"}})continue;
}
if (config.postRelatedType.ZAN === item.type) {
that.setData({
zan: { status: true, text: "Has been praised", icon: "appreciatefill"}})continue; }}},Copy the code
As for other interaction details and code details, you can read the source code to experience, if you have any questions or better implementation, you can also communicate with me.
Posters feature
Give some background
In fact, before the first small program has been implemented once, specific can refer to the use of cloud development optimization blog small program (three) – poster generation function, mainly using native Cavans for assembly, originally wanted to code copy to change on the line, but always feel that the original code is not particularly good.
I wanted to see if there was a wheel I could use, and sure enough, I found wXA-plugin-Canvas, a component that can generate beautiful posters with a very simple configuration.
Applets use NPM
Before summarizing the poster generation function, it is necessary to document the use of small program NPM to avoid unnecessary pitfalls.
Considering the size limitations of applets themselves, the NPM approach is optimal.
The reason is that according to the official documentation, only the build file generation directory in the applets NPM package is counted as the occupied space of the applets package, and only the code in this directory is uploaded when the applets code is uploaded. This greatly reduces the size of the uploaded code.
Here is a brief introduction to how to use the small program side of NPM “actually according to the official documentation to follow the steps can be”.
/miniprogram/node_modules /miniprogram /miniprogram/node_modules /miniprogram/node_modules /miniprogram/node_modules /miniprogram/node_modules
Install using commands:
npm install wxa-plugin-canvas --production
Copy the code
After the installation is successful, you can build in the small program development tool. Before building, you need to check the USE of the NPM module
Then click on the Developer Tools menu bar: Tools > Build NPM:
After the build is complete, the miniprogram_npm directory will be generated. At this point, the project side is basically tuned through.
wxa-plugin-canvas
Once built, the wXA-plugin-Canvas custom component can be used normally, which is relatively simple to use.
Start by introducing this component on the page you want:
{
"usingComponents": {"poster": "wxa-plugin-canvas/poster"}}Copy the code
Then you can use it in WSML:
<poster id="poster" hide-loading="{{false}}" preload="{{false}}" config="{{posterConfig}}" bind:success="onPosterSuccess" bind:fail="onPosterFail"></poster>
Copy the code
Since we need to obtain some data for the poster asynchronously before generating the poster, we adopt the way of generating the poster asynchronously.
Import the poster/poster.js file for this component and call it in code:
import Poster from '.. /.. /utils/poster'; Page({/** * asynchronously generate posters */onCreatePoster() {
// setThis.setdata ({posterConfig: {posterConfig... } }, () => { Poster.create(); }); }})Copy the code
Core code parsing
The data needed for the poster
Let’s take a look at the overall structure of the shared poster:
First, we need to confirm what data is needed for the composition of the poster, and obtain the corresponding data before invoking the component.
The poster I designed mainly contains three pieces of content: user information (head picture and nickname), article information (first picture, title, introduction) and the most important small program code of the article.
User information and article information is actually relatively simple, in the details page of the applet have both data, but there are two problems need to pay attention to.
The first one is the domain name problem. All the pictures used in the canvas need to be configured with the domain name, the domain name of the profile picture and the domain name of the public account
https://mmbiz.qpic.cn
https://wx.qlogo.cn
Copy the code
The image URL returned by the material list of the public account is actually HTTP, but the small program stipulated that the binding domain name must be HTTPS. At that time, I had no choice, but later I tried to use HTTPS to access the URL of the first image. Fortunately, I used the address of the first image instead:
imageUrl = imageUrl.replace('http://'.'https://')
Copy the code
Finally, the article’s small program code, the need to use small program getUnlimited API, specific can refer to the official document, has provided the cloud call way “no need to obtain access_token”, call is relatively simple.
Had originally planned to at the time of sync “adminService” directly generate corresponding article small program code, the code is written after the local debugging can, but will be uploaded to the cloud after tests found has been an error, just know originally does not support around the tyres, the trigger at the same time also does not support cloud call, so the plan fell through, I play the TODO in the code.
In this case, it will be generated when the poster is generated, and then directly uploaded to the cloud storage, and the corresponding FileID will be saved to the article collection. In this way, it can be used all the time only once generated, the specific code is as follows:
@param {} event */ asyncfunction addPostQrCode(event)
{
let scene = 'timestamp=' + event.timestamp;
let result = await cloud.openapi.wxacode.getUnlimited({
scene: scene,
page: 'pages/detail/detail'
})
if (result.errCode === 0) {
let upload = await cloud.uploadFile({
cloudPath: event.postId + '.png',
fileContent: result.buffer,
})
await db.collection("mini_posts").doc(event.postId).update({
data: {
qrCode: upload.fileID
}
});
let fileList = [upload.fileID]
let resultUrl = await cloud.getTempFileURL({
fileList,
})
return resultUrl.fileList
}
return[]}Copy the code
However, there is an awkward place here. The maximum length of scene parameter in the API that generates the mini_posts code is 32, and the length of the article ID is already 32, so we cannot splice the path to the page according to the article ID. Therefore, we temporarily use the timestamp field in the mini_posts set “theoretically unique”.
So the timestamp field also needs to be compatible in the detail page.
Poster and picture display
Poster picture display is relatively simple, use a popover, will generate a good poster picture to display:
@param {} e */ onPosterSuccess(e) {const {detail} = e; this.setData({ posterImageUrl: detail, isShowPosterModal:true
})
console.info(detail)
},
Copy the code
Save the poster image
Save images using wx. SaveImageToPhotosAlbum calling user photo albums, which need to be compatible with the user refused to photo album a series of operations, authorized by the specific code is as follows:
/** * save the poster image */ savePosterImage:function () {
let that = this
wx.saveImageToPhotosAlbum({
filePath: that.data.posterImageUrl,
success(result) {
console.log(result)
wx.showModal({
title: 'tip',
content: 'Qr code poster has been stored in the mobile phone album, please share it in moments as soon as possible',
showCancel: false,
success: function (res) {
that.setData({
isShowPosterModal: false,
isShow: false
})
}
})
},
fail: function (err) {
console.log(err);
if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
console.log("Re-authorize");
wx.showModal({
title: 'User not authorized',
content: 'If you want to save the poster image to the album, you need to obtain authorization. Is Save to Album selected in authorization Management? ',
showCancel: true,
success: function (res) {
if (res.confirm) {
console.log('User hits OK')
wx.openSetting({
success: function success(res) {
console.log('Open Settings', res.authSetting);
wx.openSetting({
success(settingdata) {
console.log(settingdata)
if (settingdata.authSetting['scope.writePhotosAlbum']) {
console.log('Succeeded in obtaining permission to save to album');
} else {
console.log('Failed to get save to album permission'); }}})}}); }}})}}}); },Copy the code
Experience summary
-
There are good open source components to take advantage of, avoid reinventing the wheel, and learn from others’ implementations if you have the opportunity.
-
Take a look at the documentation, in fact, small program documentation is really quite detailed.
-
Here I want to share the process of implementing a feature and how to successfully implement it step by step when I have an idea.
-
The small program itself is not difficult, the corresponding documentation is also very detailed, but the assembly process and the realization of logic need to think and experience. Take a look at the documentation, in fact, small program documentation is really quite detailed.
-
If your ideas and processes are clear, but you’re still not doing what you want them to do, I suggest you take a break, familiarize yourself with HTML, CSS, and javascript, and look at the documentation a few times. Maybe the problem you’re having isn’t a problem anymore.
Source link
Github.com/TencentClou…