给媳妇做一个记录心情的小程序
請勿使用本文章及源碼作為商業用途!
閑暇之余,聽媳婦嘀咕說要給她做一個能表達她每日心情的小程序,只能她在上面發東西。既然媳婦發話了,就花點心思做一個吧,因為沒有UI圖,所有布局全靠自己瞎編,下面結合圖片和代碼跟大家講解下實現過程,內容略長,感興趣的可以一覽。
下面將以圖片、代碼的形式和大家講解這個小demo的實現過程:
?首頁
首頁效果圖
首頁講解
- 音樂(下面僅展示音樂相關代碼)
1、通過wx.createInnerAudioContext()獲取實例?,安卓機上音樂能正常播放,IOS上不行,具體原因感興趣的可以去深究一下;
2、由于前面邀請函小程序相關文章發出后,問的最多的問題依然是音樂無法播放這塊,所以這個demo中就再給大家講解了下實現的原理。
- 日歷
這里日歷使用了小程序插件,之所以在首頁放一個日歷是為了頁面不顯的太單調。下面講解下插件是如何使用的:
?1、登錄微信公眾平臺>設置>第三方設置>添加插件>搜索相關插件的名字(使用appId搜索更好)>點擊某個插件右側的查看詳情,進入插件詳情頁添加插件,一般都能立馬添加通過;
2、插件詳情里面一般都有使用文檔,或git地址,插件的具體屬性事件都會在文檔里有介紹;
3、下面講解下如何在項目中使用插件:
(1)、找到src根目錄下的app.json文件,添加如下內容:
// "cloud": true, "plugins": {"calendar": {"version": "1.1.3","provider": "wx92c68dae5a8bb046"} }(2)、在需要引用該插件的頁面的.json文件中加入如下內容:
{// "navigationBarTitleText": "媳婦的心情日記",// "enablePullDownRefresh": true,"usingComponents": {"calendar": "plugin://calendar/calendar"} }(3)、在頁面中直接使用如下(具體屬性方法的意思根據對應插件有所不同):
<calendar:class="showCalendar?'':'hide_right'"class="right"weeks-type="en"cell-size="20":header="showHeader"show-more-days=truecalendar-style="demo4-calendar"board-style="demo4-board":days-color="demo4_days_style"@dayClick="dayClick" />- 天氣和地址
(1)、這里我借助的是高德微信小程序SDK;
(2)、首先獲取使用相關api需要的key值,如下:
?(3)、下載對應SDK(.js文件)并引入到項目中;
(4)、通過相關api獲取天氣和地址:
getWeather () {const that = thislet myAmapFun = new amapFile.AMapWX({key: '你申請的key'})myAmapFun.getWeather({success (res) {// 成功回調that.address = res.liveData.citythat.weather = res.liveData.weather + ' 'that.temperature = res.liveData.temperature + '℃'that.winddirection = res.liveData.winddirection + '風' + res.liveData.windpower + '級'},fail (info) {// 失敗回調console.log(info)}}) },- 發表日記
這里涉及到發表文字圖片內容,在個人小程序提交審核后很大可能是不會被通過的,雖然第一次提交我的個人小程序通過審核了,后面幾次審核均未通過,雖然我這里只限制了我和媳婦兩個人能發日記,其他人壓根看不到右下角的發布加號,但是審核人員會查代碼,代碼中一旦被他們發現有類似發表相關的內容或字樣就會導致審核不通過,好在已經通過了一次,媳婦能正常寫點東西,也算基本符合要求,遺憾的是后面實現點贊相關的功能都沒有更新到線上。
(1)、通過唯一的openId來判斷是否顯示首頁右下角的發布加號;
(2)、后面會具體講解頁面里上傳圖片到云開發及存儲到數據庫相關功能
- 點贊功能
(1)、這里點贊功能借助的小程序云開發的云函數來實現的,結合代碼:
<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>提示</h3><p>是否授權使用點贊功能?</p><div class="bottom"><button class="cancel" @tap="hideDialog">取消</button><button class="confirm" lang="zh_CN" open-type="getUserInfo" @getuserinfo="login">確認</button></div></div> </div> // 獲取日記列表 getDiaryList () {const that = thiswx.cloud.callFunction({name: 'diaryList',data: {}}).then(res => {that.getSrcFlag = falsethat.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()}) }, // 點贊或取消點贊 toLike (id, type, arr) {const that = thisthat.tempObj = {id: id,type: type,like: arr}wx.getSetting({success (res) {if (res.authSetting['scope.userInfo']) {// 已經授權,可以直接調用 getUserInfo 獲取頭像昵稱wx.getUserInfo({success: function (res) {that.userInfo = res.userInfowx.cloud.callFunction({name: 'like',data: {id: id,type: type,like: arr,name: that.userInfo.nickName}}).then(res => {if (type === '1') {tools.showToast('取消點贊成功')} else {tools.showToast('點贊成功~')}// getOpenId()方法里會執行一遍獲取日記列表that.getOpenId()})}})} else {that.showDialog = true}}}) }, // 授權獲取用戶信息 login (e) {const that = thisconsole.log(that.tempObj, e)if (e.target.errMsg === 'getUserInfo:ok') {wx.getUserInfo({success: function (res) {that.userInfo = res.userInfowx.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('取消點贊成功')} else {tools.showToast('點贊成功~')}// getOpenId()方法里會執行一遍獲取日記列表that.getOpenId()})}})}that.showDialog = false }(2)、首頁獲取日記列表,在存儲日記到數據庫集合的時候我會在每條日記對象中添加一個like屬性,like默認是一個空數組;
(3)、當用戶點贊或取消點贊時,組件data中tempObj屬性會臨時存儲三個參數①、對應日記的_id;②、用戶操作的類型是點贊(點贊是‘2’)或是取消點贊(取消點贊是‘1’);③、對應日記的like數組;
(4)、通過小程序api的wx.getSetting({})來判斷用戶是否已經授權。如果授權了獲取用戶信息,未授權則彈框引導用戶點擊確認按鈕去手動授權;
(5)、授權成功后,拿到用戶信息,我們開始調用點贊或取消點贊相關的云函數,如下:
const cloud = require('wx-server-sdk') cloud.init() const db = cloud.database() exports.main = async (event, context) => {try {// wxContext內包含用戶的openIdconst wxContext = cloud.getWXContext()// 定義空數組let arr = []if (event.like && event.like.length > 0) {// 讓定義的數組等于用戶操作的當前日記下的like數組arr = event.like// 定義一個計數變量let count = 0// 循環遍歷,當openId相同時替換like數組中的相同項,并存儲對應的typearr.forEach((item, index) => {if (item.openId === wxContext.OPENID) {count++arr.splice(index, 1, {openId: wxContext.OPENID,type: event.type,name: event.name})}})// 當計數變量為0時,說明在這條日記中,like數組中未存儲過此用戶,直接push此用戶并存儲typeif (count === 0) {arr.push({openId: wxContext.OPENID,type: event.type,name: event.name})}} else {// 如果此條日記like數組本身就為空,直接push當前用戶并存儲typearr.push({openId: wxContext.OPENID,type: event.type,name: event.name})}// 通過云開發操作數據庫的相關api,即update通過_id來更新集合中某條數據return await db.collection('diary').doc(event.id).update({data: {like: arr}})} catch (e) {console.error(e)} }(6)、相關云函數操作說明都寫在上面的注釋里,有不清楚的歡迎留言,由于點贊功能未更新到線上(原因是因為審核不通過),想體驗的同學也可以加本人微信號,提供體驗權限。
發表心情
效果圖
講解?
(1)、通過首頁右下角的發布加號,進入發布心情頁;
(2)、地址等相關信息是從首頁通過路由帶過來的;
(3)、下面重點講解下關于上傳圖片到云存儲并寫入數據庫的操作過程,內容如下:
upload () {const that = thiswx.chooseImage({count: 1,sizeType: ['compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有success: function (res) {wx.showLoading({title: '上傳中'})// 返回選定照片的本地文件路徑列表,tempFilePath可以作為img標簽的src屬性顯示圖片let filePath = res.tempFilePaths[0]const name = Math.random() * 1000000const cloudPath = 'picture/' + name + filePath.match(/\.[^.]+?$/)[0]wx.cloud.uploadFile({cloudPath, // 云存儲圖片名字filePath // 臨時路徑}).then(res => {console.log(res)wx.hideLoading()that.imgUrl = res.fileID}).catch(e => {console.log('[上傳圖片] 失敗:', e)})}}) }, save () {const that = thisif (that.desc) {that.getSrcFlag = falseconst 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('寫點什么吧~')} }(4)、這里的cloudPath可以自己定義,存儲到云中是這樣的:
(5)、我們通過組件data中的imgUrl臨時存儲手動上傳的圖片路徑,最終通過保存按鈕一起存儲到云數據庫,存如到數據庫是這樣的:
日記詳情頁
詳情頁效果圖
講解?
(1)、詳情就不過多講解,這里利用了一些小程序api,比方說動態改變頭部標題,每次進入動態隨機改變頂部標題背景,點贊數也是從首頁帶過來的;
訪客頁
效果圖
(1)、授權前
(2)、授權后
源碼地址
diary: 日記小程序(開放源碼)
體驗二維碼
由于云開發中途收費導致項目無法正常訪問,暫不開放體驗二維碼!
總結
云開發雖然能用,但對于大型項目個人還是不推薦,從圖片和數據加載這塊的效果來看,傳統服務端拿到的數據明顯要快很多,既然有這么一個免費的工具,我想感興趣的同學可以利用起來,玩點小demo,新花樣,希望這篇文章能夠幫助到有需要的同學,如果喜歡就點個贊吧~
后續優化
優化后地址
總結
以上是生活随笔為你收集整理的给媳妇做一个记录心情的小程序的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 【论文写作】如何画出好看的图表
- 下一篇: GeneXus与其它低代码平台有什么不同
