In her spare time, she murmured that to make a small program to express her daily mood, she could only send things on it.Now that your daughter-in-law has spoken, take some time to do it, because there are no UI diagrams, all the layouts are made up by herself. Here we will explain the implementation process with the pictures and codes. The content is slightly longer and you can have a look of what you are interested in.
Here's how to implement this little demo in the form of pictures, code and more:
home page
First Page Effects
Explanation on the first page
- Music (only music related codes are shown below)
<div class="bg_music" @tap="audioPlay"> <image src="../../static/images/music_icon.png" class="musicImg" :class="isPlay?'music_icon':''"/> <image src="../../static/images/music_play.png" class="music_play" :class="isPlay?'pauseImg':'playImg'"/> </div> <audio id="myAudio" :src="audioUrl" autoplay loop></audio>
data () { return { isPlay: true, audioCtx: '' } }, onLoad () { const that = this that.audioCtx = wx.createAudioContext('myAudio') that.getMusicUrl() }, methods: { getMusicUrl () { const that = this const db = wx.cloud.database() const music = db.collection('music') music.get().then(res => { that.audioUrl = res.data[0].musicUrl that.audioCtx.loop = true that.audioCtx.play() }) }, audioPlay () { const that = this if (that.isPlay) { that.audioCtx.pause() that.isPlay = !that.isPlay tools.showToast('You've paused music~') } else { that.audioCtx.play() that.isPlay = !that.isPlay tools.showToast('Background music turned on~') } } }
.bg_music position fixed right 0 top 20rpx width 100rpx z-index 99 display flex justify-content flex-start align-items flex-start .musicImg width 60rpx height 60rpx .music_icon animation musicRotate 3s linear infinite .music_play width 28rpx height 60rpx margin-left -10rpx transform-origin top -webkit-transform rotate(20deg) .playImg animation musicStop 1s linear forwards .pauseImg animation musicStart 1s linear forwards #myAudio display none
1. Get an example through wx.createInnerAudioContext(), music on Android can play normally, but not on IOS. You can go deeper for the specific reasons you are interested in.
2. Because after the previous invitation applet related articles were sent out, the most frequently asked question is that music can not play this piece, so this demo will explain to you the following principles of implementation.
- calendar
The calendar here uses the applet plug-in, so put a calendar on the front page to keep the page too monotonous.Here's how the following plug-ins are used:
1. Log in to WeChat Public Platform > Settings > Third Party Settings > Add Plug-ins > Search the name of related plug-ins (better with appId search) > Click on the right side of a plug-in to view details, enter the plug-in details page to add plug-ins, which can generally be added immediately through;
2. Documents or git addresses are commonly used in the plug-in details. The specific property events of the plug-in are described in the documents.
3. Here's how to use plug-ins in your project:
1. Locate the app.json file in the src root directory and add the following:
// "cloud": true, "plugins": { "calendar": { "version": "1.1.3", "provider": "wx92c68dae5a8bb046" } }
2. Add the following to the.json file of the page where you need to reference the plug-in:
{ // "Navigation BarTitleText": "Daughter-in-law's mood diary". // "enablePullDownRefresh": true, "usingComponents": { "calendar": "plugin://calendar/calendar" } }
3. Use the following directly on the page (the meaning of the attribute method varies depending on the plug-in):
<calendar
:class="showCalendar?'':'hide_right'"
class="right"
weeks-type="en"
cell-size="20"
:header="showHeader"
show-more-days=true
calendar-style="demo4-calendar"
board-style="demo4-board"
:days-color="demo4_days_style"
@dayClick="dayClick"
/>
- Weather and address
1. Here I am using Gaudway Credit Applet SDK;
2. First get the key value needed to use the relevant api, as follows:
3. Download the corresponding SDK (.js file) and bring it into the project;
4. Obtain weather and address through related api:
getWeather () { const that = this let myAmapFun = new amapFile.AMapWX({key: 'The one you applied for key'}) myAmapFun.getWeather({ success (res) { // Successful callback that.address = res.liveData.city that.weather = res.liveData.weather + ' ' that.temperature = res.liveData.temperature + '℃' that.winddirection = res.liveData.winddirection + 'wind' + res.liveData.windpower + 'level' }, fail (info) { // Failure Callback console.log(info) } }) },
- Publish a diary
This refers to publishing the content of text and pictures. It is very likely that the personal applet will not pass after submitting it for examination. Although the first submission to my personal applet passed the examination, the subsequent audits failed, although I only limit the ability of my daughter-in-law and me to send diaries here, others can not see the bottom right at all.Corner issue plus sign, but auditors will check the code, once they are found to have similar publication related content or words will cause the audit to fail. Fortunately, once passed, the daughter-in-law can write something normally, which is also basically in line with the requirements. Unfortunately, the functions related to point approval are not better in the future.New to Online.
1. Use the unique openId to determine if the release plus sign is displayed in the lower right corner of the first page.
2. The functions of uploading pictures to the cloud and storing them in the database will be explained later.
- Zan Zan Function
1. Here's some favor for cloud functions developed with applet cloud, combined with code:
<ul class="list"> <li class="item" v-for="(item, index) in diaryList" :key="item._id" @tap="toDetail(item)"> <image class="like" src="../../static/images/like_active.png" v-if="likeList[index] === '2'" @tap.stop="toLike(item._id, '1', item.like)"/> <image class="like" src="../../static/images/like.png" v-if="likeList[index] === '1'" @tap.stop="toLike(item._id, '2', item.like)"/> <image class="img" :src="item.url" mode="aspectFill"/> <p class="desc">{{item.desc}}</p> <div class="name-weather"> <span class="name">{{item.name}}</span> <span class="weather">{{item.weather}}</span> </div> <p class="time-address"> <span class="time">{{item.time}}</span> <!-- <span class="address">{{item.address}}</span> --> </p> </li> </ul> <div class="dialog" v-if="showDialog"> <div class="box"> <h3>Tips</h3> <p>Do you authorize the use of complimentary features?</p> <div class="bottom"> <button class="cancel" @tap="hideDialog">cancel</button> <button class="confirm" lang="zh_CN" open-type="getUserInfo" @getuserinfo="login">confirm</button> </div> </div> </div>
// Get a list of Journals getDiaryList () { const that = this wx.cloud.callFunction({ name: 'diaryList', data: {} }).then(res => { that.getSrcFlag = false that.diaryList = res.result.data.reverse() that.likeList = [] that.diaryList.forEach((item, index) => { item.like.forEach(itemSecond => { if (itemSecond.openId === that.openId) { that.likeList.push(itemSecond.type) } }) if (that.likeList.length < index + 1) { that.likeList.push('1') } }) wx.hideNavigationBarLoading() wx.stopPullDownRefresh() }) }, // Praise or Remove Praise toLike (id, type, arr) { const that = this that.tempObj = { id: id, type: type, like: arr } wx.getSetting({ success (res) { if (res.authSetting['scope.userInfo']) { // Authorized to call getUserInfo directly for Avatar nicknames wx.getUserInfo({ success: function (res) { that.userInfo = res.userInfo wx.cloud.callFunction({ name: 'like', data: { id: id, type: type, like: arr, name: that.userInfo.nickName } }).then(res => { if (type === '1') { tools.showToast('Cancel favor success') } else { tools.showToast('Comment on Success~') } // The getOpenId() method executes once to get the list of Journals that.getOpenId() }) } }) } else { that.showDialog = true } } }) }, // Authorize access to user information login (e) { const that = this console.log(that.tempObj, e) if (e.target.errMsg === 'getUserInfo:ok') { wx.getUserInfo({ success: function (res) { that.userInfo = res.userInfo wx.cloud.callFunction({ name: 'like', data: { id: that.tempObj.id, type: that.tempObj.type, like: that.tempObj.like, name: that.userInfo.nickName } }).then(res => { if (that.tempObj.type === '1') { tools.showToast('Cancel favor success') } else { tools.showToast('Comment on Success~') } // The getOpenId() method executes once to get the list of Journals that.getOpenId() }) } }) } that.showDialog = false }
2. The first page gets a list of journals. When storing journals in a database collection, I add a like attribute to each journal object. Like defaults to an empty array.
3. The tempObj property in component data temporarily stores three parameters when the user compliments or cancels the compliment:
(1) the _id of the corresponding journal;
(2) The type of user operation is to point out the favor (point out the favor is'2') or cancel the favor (cancel the favor is'1');
(3) like array corresponding to the journal;
4. Use the wx.getSetting({}) of the applet api to determine if the user is authorized.If the user is authorized to obtain user information, the pop-up box guides the user to click the confirmation button to authorize manually.
5. After the authorization is successful, we get the user information, and we begin to call the cloud functions related to the approval or cancellation of the approval, as follows:
const cloud = require('wx-server-sdk') cloud.init() const db = cloud.database() exports.main = async (event, context) => { try { // wxContext contains the user's openId const wxContext = cloud.getWXContext() // Define an empty array let arr = [] if (event.like && event.like.length > 0) { // Make the defined array equal to the like array in the current journal of the user action arr = event.like // Define a count variable let count = 0 // Loop through, replacing the same item in the like array when the openId is the same, and storing the corresponding type arr.forEach((item, index) => { if (item.openId === wxContext.OPENID) { count++ arr.splice(index, 1, { openId: wxContext.OPENID, type: event.type, name: event.name }) } }) // When the count variable is 0, the user is not stored in the like array in this journal, push the user directly and store the type if (count === 0) { arr.push({ openId: wxContext.OPENID, type: event.type, name: event.name }) } } else { // If the journal like array itself is empty, push the current user directly and store the type arr.push({ openId: wxContext.OPENID, type: event.type, name: event.name }) } // Operate databases through cloud development using the associated api, that is, update updates a piece of data in the collection through _id return await db.collection('diary').doc(event.id).update({ data: { like: arr } }) } catch (e) { console.error(e) } }
6. The operation instructions of related cloud functions are all written in the comments above. There are unclear welcome messages. As the function of clicking on approval has not been updated online (because the auditing failed), the students who want to experience can leave comments and provide experience rights.
Express your mood
Design sketch
explain
1. Enter the publishing mood page by issuing plus sign in the lower right corner of the first page;
2. Addresses and other related information are routed from the home page;
3. The following focuses on the process of uploading pictures to cloud storage and writing to the database, as follows:
upload () { const that = this wx.chooseImage({ count: 1, sizeType: ['compressed'], // You can specify whether you want the original or the compressed image, both by default sourceType: ['album', 'camera'], // You can specify whether the source is an album or a camera, both by default success: function (res) { wx.showLoading({ title: 'Uploading' }) // Returns a list of local file paths for the selected photo, tempFilePath can display the picture as an src attribute of the img tag let filePath = res.tempFilePaths[0] const name = Math.random() * 1000000 const cloudPath = 'picture/' + name + filePath.match(/\.[^.]+?$/)[0] wx.cloud.uploadFile({ cloudPath, // Cloud Storage Picture Name filePath // Temporary Path }).then(res => { console.log(res) wx.hideLoading() that.imgUrl = res.fileID }).catch(e => { console.log('[Upload pictures] Failure:', e) }) } }) }, save () { const that = this if (that.desc) { that.getSrcFlag = false const db = wx.cloud.database() const diary = db.collection('diary') if (that.imgUrl === '../../static/images/default.png') { that.imgUrl = '../../static/images/default.jpg' } diary.add({ data: { desc: that.desc, time: tools.getNowFormatDate(), url: that.imgUrl, name: that.name, weather: that.weather, address: that.address, like: [] } }).then(res => { wx.reLaunch({ url: '/pages/index/main' }) }).catch(e => { console.log(e) }) } else { tools.showToast('Write something~') } }
4. Here the cloudPath can be defined by itself and stored in the cloud as follows:
5. We store manually uploaded image paths through imgUrl temporary storage in component data, and ultimately through the Save button to the cloud database, as in the database:
Diary Details Page
Detail Page Effect Map
explain
1. Details are not too explanatory. Here we use some applet api, such as changing the header title dynamically, changing the header background dynamically and randomly each time we enter, some favorites are also brought from the first page.
Visitor Page
Design sketch
1. Before authorization
2. After authorization
summary
Although cloud development can be used, it is not recommended for individuals with large projects. From the effect of loading pictures and data, the data that traditional servers get is significantly faster. Now that there is such a free tool, I want interested students to use it, play with a little demo, new tricks.
Source Link
https://github.com/TencentCloudBase/Good-practice-tutorial-recommended
If you have technical stories / technical warfare experience related to CloudBase development using the cloud and want to share them with you, please leave a message to contact us.