雲開發實戰分享|一天搭建一個社群

騰訊云云開發發表於2019-04-01

原創:龍衣

前言

雖然不會後臺開發,但是也想自己做專案,正好雲開發出現了。開發者可以使用雲開發開發微信小程式、小遊戲,無需搭建伺服器,即可使用雲端能力。 社群作為一個交流的平臺,可以通過釋出自己、別人喜歡的文字、圖片的方式進行交流分享。 剛學完雲開發,正好可以用社群小程式專案練練手~

【社群小程式】功能實現

首頁【廣場】

●顯示使用者釋出的內容
●管理員釋出的一些教程
複製程式碼

訊息【釋出】

●釋出圖文
●水平圖片的滑動顯示
複製程式碼

個人中心【我的】

●顯示使用者的登入資訊
●使用者的收藏列表
●釋出歷史
●邀請好友
●產品意見
複製程式碼

雲開發實戰分享|一天搭建一個社群

一、首頁【廣場】

  • 顯示使用者釋出的內容
  • 管理員釋出的一些教程

實現的效果

雲開發實戰分享|一天搭建一個社群

實現要點

1.WXML 不同類別資料的顯示

通過 if-elif-else 實現,在 wxml檔案中通過 <block></block>渲染,因為它僅僅是一個包裝元素,不會在頁面中做任何渲染,只接受控制屬性。也就是說可以通過屬性來控制頁面是否要渲染這部分的內容,可以減少頁面渲染時間。

2.雲開發資料的獲取

先開通雲開發功能 ,參考官方文件,然後在建立專案的時候勾選上 使用雲開發模板(看個人吧,我直接使用後點選專案中的 login)就可以獲取到使用者的 oppenid,之後就可以使用雲資料庫了。

雲開發實戰分享|一天搭建一個社群

  • 雲開發登入:

雲開發實戰分享|一天搭建一個社群

  • 雲資料的獲取:
/**
   * 生命週期函式--監聽頁面載入
   */
  onLoad: function(options) {
    console.log('onload');
    this.getData(this.data.page);    
  },
  /**
   * 獲取列表資料
   * 
   */
  getData: function(page) {
    var that = this;
    console.log("page--->" + page);
    const db = wx.cloud.database();
    // 獲取總數
    db.collection('topic').count({
      success: function(res) {
        that.data.totalCount = res.total;
      }
    })
    // 獲取前十條
    try {
      db.collection('topic')
        .where({
          _openid: 'oSly***********vU1KwZE', // 填入當前使用者 openid
        })
        .limit(that.data.pageSize) // 限制返回數量為 10 條
        .orderBy('date', 'desc')
        .get({
          success: function(res) {
            // res.data 是包含以上定義的兩條記錄的陣列
            // console.log(res.data)
            that.data.topics = res.data;
            that.setData({
              topics: that.data.topics,
            })
            wx.hideNavigationBarLoading();//隱藏載入
            wx.stopPullDownRefresh();
            
          },
          fail: function(event) {
            wx.hideNavigationBarLoading();//隱藏載入
            wx.stopPullDownRefresh();
          }
        })
    } catch (e) {
      wx.hideNavigationBarLoading();//隱藏載入
      wx.stopPullDownRefresh();
      console.error(e);
    }
  },
複製程式碼
  • 雲資料的新增:
/**
   * 儲存到釋出集合中
   */
  saveDataToServer: function(event) {
    var that = this;
    const db = wx.cloud.database();
    const topic = db.collection('topic')
    db.collection('topic').add({
      // data 欄位表示需新增的 JSON 資料
      data: {
        content: that.data.content,
        date: new Date(),
        images: that.data.images,
        user: that.data.user,
        isLike: that.data.isLike,
      },
      success: function(res) {
        // res 是一個物件,其中有 _id 欄位標記剛建立的記錄的 id
        // 清空,然後重定向到首頁
        console.log("success---->" + res)
        // 儲存到釋出歷史
        that.saveToHistoryServer();
        // 清空資料
        that.data.content = "";
        that.data.images = [];

        that.setData({
          textContent: '',
          images: [],
        })

        that.showTipAndSwitchTab();

      },
      complete: function(res) {
        console.log("complete---->" + res)
      }
    })
  },
複製程式碼

3.資料列表的分頁

主要就是定義一個臨時陣列存放載入上來的資料,然後通過傳遞給物件,最後傳遞到佈局中去。

/**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function() {
    var that = this;
    var temp = [];
    // 獲取後面十條
    if(this.data.topics.length < this.data.totalCount){
      try {
        const db = wx.cloud.database();
        db.collection('topic')
          .skip(5)
          .limit(that.data.pageSize) // 限制返回數量為 5 條
          .orderBy('date', 'desc')	// 排序
          .get({
            success: function (res) {
              // res.data 是包含以上定義的兩條記錄的陣列
              if (res.data.length > 0) {
                for(var i=0; i < res.data.length; i++){
                  var tempTopic = res.data[i];
                  console.log(tempTopic);
                  temp.push(tempTopic);
                }

                var totalTopic = {};
                totalTopic =  that.data.topics.concat(temp);

                console.log(totalTopic);
                that.setData({
                  topics: totalTopic,
                })
              } else {
                wx.showToast({
                  title: '沒有更多資料了',
                })
              }


            },
            fail: function (event) {
              console.log("======" + event);
            }
          })
      } catch (e) {
        console.error(e);
      }
    }else{
      wx.showToast({
        title: '沒有更多資料了',
      })
    }
    
  },
複製程式碼

二、訊息【釋出】

  • 釋出圖文
  • 水平圖片的滑動顯示(效果不是很好,可以改為九宮格實現)

釋出頁面效果如下:

雲開發實戰分享|一天搭建一個社群

分析如何實現

  • 導航欄的實現很簡單就不說了,可參考我之前的文章
  • 重點是中間的 ② 是內容區域
  • 區域三是功能操作區

內容區域的實現

  • 第一個是文字區域
  • 第二個是水平的圖片展示區域

在圖片的右上角有關閉按鈕,這裡使用的是 icon元件。

主要的實現程式碼如下:

<view class="content">
  <form bindsubmit="formSubmit">
    <view class="text-content">
      <view class='text-area'>
        <textarea name="input-content" type="text" placeholder="說點什麼吧~" placeholder-class="holder" value="{{textContent}}" bindblur='getTextAreaContent'></textarea>
      </view>

    </view>
    <scroll-view class="image-group" scroll-x="true">
      <block wx:for='{{images}}' wx:for-index='idx'>
      <view>
        <image src='{{images[idx]}}' mode='aspectFill' bindtap="previewImg"></image>
        <icon type='clear' bindtap='removeImg'  data-index="{{idx}}" ></icon>
      </view>
      </block>
      
    </scroll-view>
    <view class='btn-func'>
      <button class="btn-img" bindtap='chooseImage'>選擇圖片</button>
      <button class="btn" formType='submit'  open-type="getUserInfo">釋出圈圈</button>
      <!-- <image hidden=''></image> -->
    </view>
  </form>

</view>
複製程式碼

佈局樣式如下:

.content {
  height: 100%;
  width: 100%;
}

textarea {
  width: 700rpx;
  padding: 25rpx 0;
}

.text-content {
  background-color: #f3efef;
  padding: 0 25rpx;
}

.image-group {
  display: flex;
  white-space: nowrap;
  margin-top: 30px;
}

.image-group view{
  display: inline-block;
  flex-direction: row;
  width: 375rpx;
  height: 375rpx;
  margin-right: 20rpx;
  margin-left: 20rpx;
  background-color: #cfcccc;
}

.image-group view image{
  width: 100%;
  height: 100%;
  align-items: center;
}

.image-group view icon{
  display: inline-block;
  vertical-align: top;
  position: absolute
}
.btn-func {
  display: flex;
  flex-direction: column;
  width: 100%;
  position: absolute;
  bottom: 0;
  margin: 0 auto;
  align-items: center;
}

.btn-img {
  width: 220px;
  height: 45px;
  line-height: 45px;
  margin-top: 20px;
  margin-bottom: 20px;
  background-color: rgb(113, 98, 250);
  color: #fff;
  border-radius: 50px;
}

.btn {
  width: 220px;
  height: 45px;
  line-height: 45px;
  background-color: #d50310;
  color: #fff;
  border-radius: 50px;
  margin-bottom: 20px;
}
複製程式碼

頁面佈局之後就該從 js中去處理資料了,在 js中主要實現的功能有:

  • 文字內容的獲取
  • 圖片的選擇
  • 圖片的閱覽
  • 圖片的刪除
  • 將結果釋出到雲資料庫中

1.文字內容的獲取

 /**
   * 獲取填寫的內容
   */
  getTextAreaContent: function(event) {
    this.data.content = event.detail.value;
  },
複製程式碼

2.圖片的選擇

 /**
   * 選擇圖片
   */
  chooseImage: function(event) {
    var that = this;
    wx.chooseImage({
      count: 6,
      success: function(res) {
        // tempFilePath可以作為img標籤的src屬性顯示圖片
        const tempFilePaths = res.tempFilePaths

        for (var i in tempFilePaths) {
          that.data.images = that.data.images.concat(tempFilePaths[i])
        }
        // 設定圖片
        that.setData({
          images: that.data.images,
        })
      },
    })
  },
複製程式碼

3.圖片的預覽

 // 預覽圖片
  previewImg: function(e) {
    //獲取當前圖片的下標
    var index = e.currentTarget.dataset.index;

    wx.previewImage({
      //當前顯示圖片
      current: this.data.images[index],
      //所有圖片
      urls: this.data.images
    })
  },
複製程式碼

4.圖片的刪除

/**
   * 刪除圖片
   */
  removeImg: function(event) {
    var position = event.currentTarget.dataset.index;
    this.data.images.splice(position, 1);
    // 渲染圖片
    this.setData({
      images: this.data.images,
    })
  },
複製程式碼

5.釋出內容到資料庫中

資料釋出到資料中,需要先開啟雲開發,然後在資料庫中建立集合也就是表之後就是呼叫資料庫的增刪改查API即可。

 /**
   * 新增到釋出集合中
   */
  saveToHistoryServer: function(event) {
    var that = this;
    const db = wx.cloud.database();
    db.collection('history').add({
      // data 欄位表示需新增的 JSON 資料
      data: {
        content: that.data.content,
        date: new Date(),
        images: that.data.images,
        user: that.data.user,
        isLike: that.data.isLike,
      },
      success: function(res) {
        // res 是一個物件,其中有 _id 欄位標記剛建立的記錄的 id
        console.log(res)
      },
      fail: console.error
    })
  },
複製程式碼

三、個人中心【我的】

  • 【顯示使用者的登入資訊】主要就是呼叫小程式介面,獲取使用者的微信公開資訊進行展示
  • 【使用者的收藏列表】獲取資料庫中的收藏列表進行展示
  • 【釋出歷史】在釋出頁面,當釋出成功將資料存到釋出歷史表中,需要的時候獲取該表的資料進行展示
  • 【邀請好友】呼叫小程式的分享介面,直接分享給微信群,或者個人
  • 【產品意見】一個類似於釋出頁的頁面,實現思路和釋出頁實現是一樣的。

實現的效果

雲開發實戰分享|一天搭建一個社群

實現分析

1.要實現的效果

  • 在使用者進入個人中心,直接彈出獲取使用者資訊彈窗
  • 顯示圓形的使用者頭像

2.授權彈窗

官方獲取使用者資訊文件調整

為優化使用者體驗,使用 wx.getUserInfo 介面直接彈出授權框的開發方式將逐步不再支援。從2018年4月30日開始,小程式與小遊戲的體驗版、開發版呼叫 wx.getUserInfo 介面,將無法彈出授權詢問框,預設呼叫失敗。正式版暫不受影響。

也就是以前的 wx.getUserInfo不直接彈出授權視窗了,而且在新版中呼叫會直接返回fail,現在的做法呢就是通過點選一個button 去實現使用者授權功能。

文件中說明了有兩種方式能夠獲取使用者資訊。

  • 一個是利用 <open-data>獲取公開的使用者資訊:
<open-data type="userNickName" lang="zh_CN"></open-data>
<open-data type="userAvatarUrl"></open-data>
<open-data type="userGender" lang="zh_CN"></open-data>
複製程式碼
  • 另一個是利用button 元件將 open-type 指定為 getUserInfo型別:
  <!-- 需要使用 button 來授權登入 -->
  <button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">授權登入</button>
  <view wx:else>請升級微信版本</view>

Page({
  data: {
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  onLoad: function() {
    // 檢視是否授權
    wx.getSetting({
      success (res){
        if (res.authSetting['scope.userInfo']) {
          // 已經授權,可以直接呼叫 getUserInfo 獲取頭像暱稱
          wx.getUserInfo({
            success: function(res) {
              console.log(res.userInfo)
            }
          })
        }
      }
    })
  },
  bindGetUserInfo (e) {
  // 獲取到使用者資訊
    console.log(e.detail.userInfo)
  }
})
複製程式碼

3.中實現圓形頭像

<view class='amountBg'>
  <view class='img'>
    <open-data type="userAvatarUrl"></open-data>
  </view>
  <view class='account'>
    <view class='nick-name'>
      <open-data type="userNickName" lang="zh_CN"></open-data>
    </view>
    <view class='address'>
      <open-data type="userCountry" lang="zh_CN"></open-data>·
      <open-data type="userProvince" lang="zh_CN"></open-data>·
      <open-data type="userCity" lang="zh_CN"></open-data>
    </view>
  </view>
</view>
複製程式碼

css 樣式如下:

.amountBg {
  display: flex;
  flex-direction: row;
  height: 100px;
  background-color: #5495e6;
  align-items: center;
}

.img {
  overflow: hidden;
  display: block;
  margin-left: 20px;
  width: 49px;
  height: 49px;
  border-radius: 50%;
}

.account {
  width: 70%;
  color: #fff;
  margin-left: 10px;
  align-items: center;
}

.nick-name{
  font-family: 'Mcrosoft Yahei';
  font-size: 16px;
}

.address{
  font-size: 13px;
}
.nav {
  width: 15px;
  color: #fff;
}
複製程式碼

可能存在的一些問題

  • 其他使用者釋出的內容,有時候顯示不出來? 將資料庫的許可權設定為全部人可見。
  • 釋出內容之後返回首頁沒有自動重新整理? 在廣場首頁 onShow 的時候獲取資料庫的資料進行展示。
  • clone 原始碼後執行不起來? 需要在自己的雲資料庫中建立對應的表。

相關文章