mpvue+小程序雲開發,純前端實現婚禮邀請函(相冊小程序)

請勿使用本文章及源碼作為商業用途!

前言

當初做這個小程序是為了婚禮前的需要,結婚之後,希望這個小程序能夠留存下來,特地花了一些空閑時間將小程序轉化成為“相冊類小程序”

體驗碼

準備工作

  1. mpvue框架 
  2. 小程序·雲開發 

注意:使用mpvue前,首先你得先熟悉vue框架的基本使用 

項目結構介紹

注意:接下來展示的代碼,有幾個對比,分別是本人優化前和優化后的代碼對比,感興趣的可以着重看一下優化后的成熟寫法。

  • common目錄: 放一些公共資源,如js,css,json
  • components目錄:組件相關的.vue文件都放在這裏
  • pages目錄:所有頁面都放在這個目錄
  • utils目錄:使用mpvue時自動生成,可忽略
  • app.json文件:
{
  "pages": [ "pages/index/main", "pages/photo/main", "pages/map/main", "pages/greet/main", "pages/message/main" ], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "WeChat", "navigationBarTextStyle": "black" }, "tabBar": { "color": "#ccc", "selectedColor": "#ff4c91", "borderStyle": "white", "backgroundColor": "#ffffff", "list": [ { "pagePath": "pages/index/main", "iconPath": "static/images/1-1.png", "selectedIconPath": "static/images/1-2.png", "text": "邀請函" }, { "pagePath": "pages/photo/main", "iconPath": "static/images/2-1.png", "selectedIconPath": "static/images/2-2.png", "text": "甜蜜相冊" }, { "pagePath": "pages/map/main", "iconPath": "static/images/3-1.png", "selectedIconPath": "static/images/3-2.png", "text": "酒店導航" }, { "pagePath": "pages/greet/main", "iconPath": "static/images/4-1.png", "selectedIconPath": "static/images/4-2.png", "text": "好友祝福" }, { "pagePath": "pages/message/main", "iconPath": "static/images/5-1.png", "selectedIconPath": "static/images/5-2.png", "text": "留言評論" } ] }, "requiredBackgroundModes": ["audio"] }
  • App.vue文件 (本人主要是為了增加項目更新后的提醒),所以在這個文件加了些相關內容,內容如下:
<script>
export default { onLaunch () { // 檢測小程序是否有新版本更新 if (wx.canIUse('getUpdateManager')) { const updateManager = wx.getUpdateManager() updateManager.onCheckForUpdate(function (res) { // 請求完新版本信息的回調 if (res.hasUpdate) { updateManager.onUpdateReady(function () { wx.showModal({ title: '更新提示', content: '新版本已經準備好,是否重啟應用?', success: function (res) { if (res.confirm) { // 新的版本已經下載好,調用 applyUpdate 應用新版本並重啟  updateManager.applyUpdate() } } }) }) // 小程序有新版本,會主動觸發下載操作(無需開發者觸發)  wx.getUpdateManager().onUpdateFailed(function () { // 當新版本下載失敗,會進行回調  wx.showModal({ title: '提示', content: '檢查到有新版本,下載失敗,請檢查網絡設置', showCancel: false }) }) } }) } else { // 版本過低則無法使用該方法  wx.showModal({ title: '提示', confirmColor: '#5BB53C', content: '當前微信版本過低,無法使用該功能,請升級到最新微信版本后重試。' }) } } } </script> <style lang="stylus"> page height 100% image display block </style>
  • main.js文件:
import Vue from 'vue'
import App from './App' Vue.config.productionTip = false App.mpType = 'app' wx.cloud.init({ env: '雲開發環境ID' }) const app = new Vue(App) app.$mount()
  • functions目錄:主要放一些雲函數,這裏不清楚雲函數的文章後面會提及
  • images目錄:主要放一些靜態資源圖片

頁面介紹

首頁——邀請函

首頁着重和大家講解下背景音樂的實現方法

const audioCtx = wx.createInnerAudioContext()

 接口獲取實例

接着,通過實例的相關方法來實現音樂的播放與暫停功能

具體代碼如下:

<script>
import IndexSwiper from 'components/indexSwiper' import tools from 'common/js/h_tools' const audioCtx = wx.createInnerAudioContext() export default { name: 'Index', components: { IndexSwiper }, data () { return { isPlay: true, list: [] } }, onShow () { const that = this that.isPlay = true that.getMusicUrl() }, methods: { audioPlay () { const that = this if (that.isPlay) { audioCtx.pause() that.isPlay = false tools.showToast('您已暫停音樂播放~') } else { audioCtx.play() that.isPlay = true tools.showToast('背景音樂已開啟~') } }, getList () { const that = this const db = wx.cloud.database() const banner = db.collection('banner') banner.get().then(res => { that.list = res.data[0].bannerList }) }, getMusicUrl () { const that = this const db = wx.cloud.database() const music = db.collection('music') music.get().then(res => { let musicUrl = res.data[0].musicUrl audioCtx.src = musicUrl audioCtx.loop = true audioCtx.play() that.getList() }) } }, onShareAppMessage: function (res) { return { path: '/pages/index/main' } } } </script>

以上代碼中使用到了雲開發相關功能,文章後面會介紹,請大家稍安勿躁

相冊頁——就一個輪播圖,這裏就不過多介紹

地圖頁——這裏着重講一下地圖標籤map

map標籤 

這裏講一下標記點markers:

data () {
    return { // qqSdk: '',  markers: [{ iconPath: '../../static/images/nav.png', id: 0, latitude: 30.08059, longitude: 115.93027, width: 50, height: 50 }] } }
<template>
    <div class="map">
        <image mode="aspectFit" class="head-img" src="../../static/images/t1.png"/>
        <map class="content" id="map" longitude="115.93027" latitude="30.08059" :markers="markers" scale="18" @tap="toNav">
        </map>
        <div class="call">
            <div class="left" @tap="linkHe">
                <image src="../../static/images/he.png"/>
                <span>呼叫新郎</span>
            </div>
            <div class="right" @tap="linkShe">
                <image src="../../static/images/she.png"/>
                <span>呼叫新娘</span>
            </div>
        </div>
        <image class="footer" src="../../static/images/grren-flower-line.png"/>
    </div>
</template>

祝福頁——也是雲開發相關內容,後面會介紹

留言頁——也是雲開發相關內容,後面會介紹

雲開發介紹

project.config.json文件:

"cloudfunctionRoot": "static/functions/"

進行雲開發首先我們需要找到上面這個文件,在上面這個json文件中加上上面這行代碼

cloudfunctionRoot 用於指定存放雲函數的目錄

app.json文件:

"window": {
    "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "WeChat", "navigationBarTextStyle": "black" }, "cloud": true

增加字段 "cloud": true實現雲開發能力的兼容性

開通雲開發

在開發者工具工具欄左側,點擊 “雲開發” 按鈕即可開通雲開發

雲開發控制台

數據庫

 雲開發提供了一個 JSON 數據庫

 

存儲

 

雲開發提供了一塊存儲空間,提供了上傳文件到雲端、帶權限管理的雲端下載能力,開發者可以在小程序端和雲函數端通過 API 使用雲存儲功能。

 

雲函數

 

雲函數是一段運行在雲端的代碼,無需管理服務器,在開發工具內編寫、一鍵上傳部署即可運行後端代碼。

使用雲開發

雲能力初始化

在小程序端開始使用雲能力前,需先調用 wx.cloud.init 方法完成雲能力初始化

import Vue from 'vue'
import App from './App' Vue.config.productionTip = false App.mpType = 'app' wx.cloud.init({ env: '雲開發環境ID' }) const app = new Vue(App) app.$mount()

數據庫的使用

在開始使用數據庫 API 進行增刪改查操作之前,需要先獲取數據庫的引用。以下調用獲取默認環境的數據庫的引用:

const db = wx.cloud.database()

 要操作一個集合,需先獲取它的引用:

const todos = db.collection('todos')

操作數據庫的相關示例

例:首頁獲取背景音樂資源

getMusicUrl () {
      const that = this const db = wx.cloud.database() const music = db.collection('music') music.get().then(res => { let musicUrl = res.data[0].musicUrl audioCtx.src = musicUrl audioCtx.loop = true audioCtx.play() that.getList() }) }

 例:首頁獲取輪播圖數組

getList () {
      const that = this const db = wx.cloud.database() const banner = db.collection('banner') banner.get().then(res => { that.list = res.data[0].bannerList }) }

例:祝福頁,用戶送上祝福存儲用戶

<script>
import tools from 'common/js/h_tools' export default { name: 'Greet', data () { return { userList: [], openId: '', userInfo: '' } }, onShow () { const that = this that.getUserList() }, methods: { scroll (e) { console.log(e) }, sendGreet (e) { const that = this if (e.target.errMsg === 'getUserInfo:ok') { wx.getUserInfo({ success: function (res) { that.userInfo = res.userInfo that.getOpenId() } }) } }, addUser () { const that = this const db = wx.cloud.database() const user = db.collection('user') user.add({ data: { user: that.userInfo } }).then(res => { that.getUserList() }) }, getOpenId () { const that = this wx.cloud.callFunction({ name: 'user', data: {} }).then(res => { that.openId = res.result.openid that.getIsExist() }) }, getIsExist () { const that = this const db = wx.cloud.database() const user = db.collection('user') user.where({ _openid: that.openId }).get().then(res => { if (res.data.length === 0) { that.addUser() } else { tools.showToast('您已經送過祝福了~') } }) }, getUserList () { const that = this wx.cloud.callFunction({ name: 'userList', data: {} }).then(res => { that.userList = res.result.data.reverse() }) } } } </script>

獲取送祝福的好友列表

getUserList () {
      const that = this wx.cloud.callFunction({ name: 'userList', data: {} }).then(res => { that.userList = res.result.data.reverse() }) }

這裏用到了雲函數,之所以用雲函數是因為小程序端在獲取集合數據時服務器一次默認並且最多返回 20 條記錄,雲函數端這個数字則是 100。

雲函數的使用方法

上面我們講過在project.config.json文件中配置雲函數存放位置

下面是雲函數messageList的index.js文件:

不成熟寫法:

const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database() const MAX_LIMIT = 100 exports.main = async (event, context) => { // 先取出集合記錄總數 const countResult = await db.collection('message').count() const total = countResult.total // 計算需分幾次取 const batchTimes = Math.ceil(total / 100) // 承載所有讀操作的 promise 的數組 const tasks = [] for (let i = 0; i < batchTimes; i++) { const promise = db.collection('message').skip(i * MAX_LIMIT).limit(MAX_LIMIT).get() tasks.push(promise) } // 等待所有 return (await Promise.all(tasks)).reduce((acc, cur) => ({ data: acc.data.concat(cur.data), errMsg: acc.errMsg })) }

成熟寫法(分頁查詢):

const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database() exports.main = async (event, context) => { const wxContext = cloud.getWXContext() const dbName = 'message' const filter = event.filter ? event.filter : null const pageNum = event.pageNum ? event.pageNum : 1 const pageSize = event.pageSize ? event.pageSize : 10 const countResult = await db.collection(dbName).where(filter).count() const total = countResult.total const totalPage = Math.ceil(total / pageSize) let hasMore if (pageNum >= totalPage) { hasMore = false } else { hasMore = true } return db.collection(dbName).orderBy('time', 'desc').where(filter).skip((pageNum - 1) * pageSize).limit(pageSize).get().then(res => { res.hasMore = hasMore res.total = total res.openId = wxContext.OPENID return res }) }

使用雲函數前,在開發者工具上,找到messageList目錄,右鍵如圖:

 點擊上傳並部署:雲端安裝依賴(不上傳node_modules)

得到如圖的提示:

 安裝完點擊完成就能使用當前雲函數了,使用方法即:

getUserList () {
      const that = this wx.cloud.callFunction({ name: 'userList', data: {} }).then(res => { that.userList = res.result.data.reverse() }) }

數組之所以要倒序是因為希望新祝福的的用戶在最前面显示 

用戶送上祝福的時候存儲用戶

這裏我們用到了雲函數獲取用戶信息,

當小程序端調用雲函數時,雲函數的傳入參數中會被注入小程序端用戶的 openid,開發者無需校驗 openid 的正確性,因為微信已經完成了這部分鑒權,開發者可以直接使用該 openid

不成熟寫法:

下面是雲函數user的index.js文件:

// 雲函數入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 雲函數入口函數
exports.main = async (event, context) => { const wxContext = cloud.getWXContext() return { event, openid: wxContext.OPENID, appid: wxContext.APPID, unionid: wxContext.UNIONID } }

主要是為了獲取當前操作用戶的openid,獲取當前用戶的openid方法:

getOpenId () {
      const that = this wx.cloud.callFunction({ name: 'user', data: {} }).then(res => { that.openId = res.result.openid that.getIsExist() }) }

接着判斷當前用戶是否已經存在於數據庫中,即getIsExist()方法:

getIsExist () {
      const that = this const db = wx.cloud.database() const user = db.collection('user') user.where({ _openid: that.openId }).get().then(res => { if (res.data.length === 0) { that.addUser() } else { tools.showToast('您已經送過祝福了~') } }) }

如果得到的數組長度為零則添加改用戶到數據庫,否則則提醒當前用戶已經送過祝福

接下來介紹存儲用戶信息的方法,即addUser():

addUser () {
      const that = this const db = wx.cloud.database() const user = db.collection('user') user.add({ data: { user: that.userInfo } }).then(res => { that.getUserList() }) }

存入到數據庫的信息是這樣的:

成熟寫法(使用雲函數一次搞定):

// 雲函數入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database() exports.main = async (event, context) => { const wxContext = cloud.getWXContext() const dbName = 'user' const filter = { _openid: wxContext.OPENID } const countResult = await db.collection(dbName).where(filter).count() const total = countResult.total if (total) { return { has: true } } else { return db.collection(dbName).add({ data: { user: event.user, _openid: wxContext.OPENID, time: db.serverDate() } }) } }
toMessage (e) {
      const that = this
      if (e.target.errMsg === 'getUserInfo:ok') { wx.getUserInfo({ success: function (res) { that.userInfo = res.userInfo wx.navigateTo({ url: `/pages/writeMessage/main?avatar=${that.userInfo.avatarUrl}&name=${that.userInfo.nickName}`  }) that.addUser(that.userInfo) } }) } }, addUser (obj) { wx.cloud.callFunction({ name: 'addUser', data: { user: obj } }) }

總結 

大概的功能就是這麼多,希望可以幫助到大家,覺得寫得不錯的記得給作者點個贊,你們的支持是我不斷更新的最大動力!

源碼地址

後續優化

  • 留言審核
  • 一些動畫效果
  • 分頁處理
  • 雲函數優化
  • 回到頂部

最後

一開始不清楚隨筆和文章的區別,還是希望這篇隨筆能展示在博客園首頁(所以改成隨筆),讓更多的朋友看到

希望對那些有想法又不會後台開發的朋友一些啟示作用,祝你早日做出只屬於自己的小程序。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益