你的心事我全知曉——心情日記小程序丨實戰

閒暇之餘,聽媳婦嘀咕說要給她作一個能表達她每日心情的小程序,只能她在上面發東西。既然媳婦發話了,就花點心思作一個吧,由於沒有UI圖,全部佈局全靠本身瞎編,下面結合圖片和代碼跟你們講解下實現過程,內容略長,感興趣的能夠一覽。javascript

下面將以圖片、代碼的形式和你們講解這個小demo的實現過程:css

首頁

首頁效果圖

首頁講解

  • 音樂(下面僅展現音樂相關代碼)
<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>
```</br>

```javascript
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('您已暫停音樂播放~')
    } else {
      that.audioCtx.play()
      that.isPlay = !that.isPlay
      tools.showToast('背景音樂已開啓~')
    }
  }
}
```</br>

```css
.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
複製代碼

一、經過wx.createInnerAudioContext()獲取實例 ,安卓機上音樂能正常播放,IOS上不行,具體緣由感興趣的能夠去深究一下;html

二、因爲前面邀請函小程序相關文章發出後,問的最多的問題依然是音樂沒法播放這塊,因此這個demo中就再給你們講解了下實現的原理。java


  • 日曆

這裏日曆使用了小程序插件,之因此在首頁放一個日曆是爲了頁面不顯的太單調。下面講解下插件是如何使用的:git

一、登陸微信公衆平臺>設置>第三方設置>添加插件>搜索相關插件的名字(使用appId搜索更好)>點擊某個插件右側的查看詳情,進入插件詳情頁添加插件,通常都能立馬添加經過;github

二、插件詳情裏面通常都有使用文檔,或git地址,插件的具體屬性事件都會在文檔裏有介紹;web

三、下面講解下如何在項目中使用插件:數據庫

一、找到src根目錄下的app.json文件,添加以下內容:

// "cloud": true,
"plugins": {
  "calendar": {
    "version": "1.1.3",
    "provider": "wx92c68dae5a8bb046"
  }
}
複製代碼

二、在須要引用該插件的頁面的.json文件中加入以下內容:

{
  // "navigationBarTitleText": "媳婦的心情日記",
  // "enablePullDownRefresh": true,
  "usingComponents": {
    "calendar": "plugin://calendar/calendar"
  }
}
複製代碼

三、在頁面中直接使用以下(具體屬性方法的意思根據對應插件有所不一樣):

<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" />
複製代碼

  • 天氣和地址

一、這裏我藉助的是高德微信小程序SDK;json

二、首先獲取使用相關api須要的key值,以下:小程序

三、下載對應SDK(.js文件)並引入到項目中;

四、經過相關api獲取天氣和地址:

getWeather () {
  const that = this
  let myAmapFun = new amapFile.AMapWX({key: '你申請的key'})
  myAmapFun.getWeather({
    success (res) {
      // 成功回調
      that.address = res.liveData.city
      that.weather = res.liveData.weather + ' '
      that.temperature = res.liveData.temperature + '℃'
      that.winddirection = res.liveData.winddirection + '風' + res.liveData.windpower + '級'
    },
    fail (info) {
      // 失敗回調
      console.log(info)
    }
  })
},
複製代碼

  • 發表日記

這裏涉及到發表文字圖片內容,在我的小程序提交審覈後很大多是不會被經過的,雖然第一次提交個人我的小程序經過審覈了,後面幾回審覈均未經過,雖然我這裏只限制了我和媳婦兩我的能發日記,其餘人壓根看不到右下角的發佈加號,可是審覈人員會查代碼,代碼中一旦被他們發現有相似發表相關的內容或字樣就會致使審覈不經過,好在已經經過了一次,媳婦能正常寫點東西,也算基本符合要求,遺憾的是後面實現點贊相關的功能都沒有更新到線上。

一、經過惟一的openId來判斷是否顯示首頁右下角的發佈加號;

二、後面會具體講解頁面裏上傳圖片到雲開發及存儲到數據庫相關功能


  • 點贊功能

一、這裏點贊功能借助的小程序雲開發的雲函數來實現的,結合代碼:

<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>
```</br>

```javascript
// 獲取日記列表
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() }) }, // 點贊或取消點贊 toLike (id, type, arr) { const that = this that.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.userInfo wx.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 = 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('取消點同意功')
          } else {
            tools.showToast('點同意功~')
          }
          // getOpenId()方法裏會執行一遍獲取日記列表
          that.getOpenId()
        })
      }
    })
  }
  that.showDialog = false
}
複製代碼

二、首頁獲取日記列表,在存儲日記到數據庫集合的時候我會在每條日記對象中添加一個like屬性,like默認是一個空數組;

三、當用戶點贊或取消點贊時,組件data中tempObj屬性會臨時存儲三個參數: ①、對應日記的_id; ②、用戶操做的類型是點贊(點贊是‘2’)或是取消點贊(取消點贊是‘1’); ③、對應日記的like數組;

四、經過小程序api的wx.getSetting({})來判斷用戶是否已經受權。若是受權了獲取用戶信息,未受權則彈框引導用戶點擊確認按鈕去手動受權;

五、受權成功後,拿到用戶信息,咱們開始調用點贊或取消點贊相關的雲函數,以下:

const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
exports.main = async (event, context) => {
  try {
    // wxContext內包含用戶的openId
    const wxContext = cloud.getWXContext()
    // 定義空數組
    let arr = []
    if (event.like && event.like.length > 0) {
      // 讓定義的數組等於用戶操做的當前日記下的like數組
      arr = event.like
      // 定義一個計數變量
      let count = 0
      // 循環遍歷,當openId相同時替換like數組中的相同項,並存儲對應的type
      arr.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此用戶並存儲type
      if (count === 0) {
        arr.push({
          openId: wxContext.OPENID,
          type: event.type,
          name: event.name
        })
      }
    } else {
      // 若是此條日記like數組自己就爲空,直接push當前用戶並存儲type
      arr.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)
  }
}
複製代碼

六、相關雲函數操做說明都寫在上面的註釋裏,有不清楚的歡迎留言,因爲點贊功能未更新到線上(緣由是由於審覈不經過),想體驗的同窗能夠留下評論,提供體驗權限。


發表心情

效果圖

講解

一、經過首頁右下角的發佈加號,進入發佈心情頁;

二、地址等相關信息是從首頁經過路由帶過來的;

三、下面重點講解下關於上傳圖片到雲存儲並寫入數據庫的操做過程,內容以下:

upload () {
  const that = this
  wx.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() * 1000000
      const 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 = 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('寫點什麼吧~')
  }
}
複製代碼

四、這裏的cloudPath能夠本身定義,存儲到雲中是這樣的:

五、咱們經過組件data中的imgUrl臨時存儲手動上傳的圖片路徑,最終經過保存按鈕一塊兒存儲到雲數據庫,存如到數據庫是這樣的:


日記詳情頁

詳情頁效果圖

講解

一、詳情就不過多講解,這裏利用了一些小程序api,比方說動態改變頭部標題,每次進入動態隨機改變頂部標題背景,點贊數也是從首頁帶過來的;


訪客頁

效果圖

一、受權前

二、受權後


總結

雲開發雖然能用,但對於大型項目我的仍是不推薦,從圖片和數據加載這塊的效果來看,傳統服務端拿到的數據明顯要快不少,既然有這麼一個免費的工具,我想感興趣的同窗能夠利用起來,玩點小demo,新花樣。

源碼連接

github.com/TencentClou…

若是你有關於使用雲開發CloudBase相關的技術故事/技術實戰經驗想要跟你們分享,歡迎留言聯繫咱們哦~比心!

相關文章
相關標籤/搜索