国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

小程序·云開發(fā)實戰(zhàn)實戰(zhàn) - 迷你微博

caozhijian / 2856人閱讀

摘要:根據(jù)上一小節(jié)的主要信息,我們可以初步推斷出一條迷你微博在云數(shù)據(jù)庫的里是這樣存儲的先來看。

0. 前言

本文將手把手教你如何寫出迷你版微博的一行行代碼,迷你版微博包含以下功能:

Feed 流:關注動態(tài)、所有動態(tài)

發(fā)送圖文動態(tài)

搜索用戶

關注系統(tǒng)

點贊動態(tài)

個人主頁

使用到的云開發(fā)能力:

云數(shù)據(jù)庫

云存儲

云函數(shù)

云調用

沒錯,幾乎是所有的云開發(fā)能力。也就是說,讀完這篇實戰(zhàn),你就相當于完全入門了云開發(fā)!

咳咳,當然,實際上這里只是介紹核心邏輯和重點代碼片段,完整代碼建議下載查看。

1. 取得授權

作為一個社交平臺,首先要做的肯定是經過用戶授權,獲取用戶信息,小程序提供了很方便的接口:

這個 button 有個 open-type 屬性,這個屬性是專門用來使用小程序的開放能力的,而 getUserInfo 則表示 獲取用戶信息,可以從bindgetuserinfo回調中獲取到用戶信息。

于是我們可以在 wxml 里放入這個 button 后,在相應的 js 里寫如下代碼:

Page({
  ...

  getUserInfo: function(e) {
    wx.navigateTo({
      url: "/pages/circle/circle"
    })
  },

  ...
})

這樣在成功獲取到用戶信息后,我們就能跳轉到迷你微博頁面了。

需要注意,不能使用 wx.authorize({scope: "scope.userInfo"}) 來獲取讀取用戶信息的權限,因為它不會跳出授權彈窗。目前只能使用上面所述的方式實現(xiàn)。

2. 主頁設計

社交平臺的主頁大同小異,主要由三個部分組成:

Feed 流

消息

個人信息

那么很容易就能想到這樣的布局(注意新建一個 Page 哦,路徑:pages/circle/circle.wxml):


  
  

  
  

  
  

  
    
      
    
    
      
    
    
      
    
  

很好理解,畫面主要被分為上下兩個部分:上面的部分是主要內容,下面的部分是三個 Tab 組成的 Footer。重點 WXSS 實現(xiàn)(完整的 WXSS 可以下載源碼查看):

.footer {
  box-shadow: 0 0 15rpx #ccc;
  display: flex;
  position: fixed;
  height: 120rpx;
  bottom: 0;
  width: 100%;
  flex-direction: row;
  justify-content: center;
  z-index: 100;
  background: #fff;
}

.footer-item {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  width: 33.33%;
  color: #333;
}

.footer-item:nth-child(2) {
  border-left: 3rpx solid #aaa;
  border-right: 3rpx solid #aaa;
  flex-grow: 1;
}

.footer-btn {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 0;
  font-size: 30rpx;
}

核心邏輯是通過 position: fixed 來讓 Footer 一直在下方。

讀者會發(fā)現(xiàn)有一個 currentPage 的 data ,這個 data 的作用其實很直觀:通過判斷它的值是 main/msg/me 中的哪一個來決定主要內容。同時,為了讓首次使用的用戶知道自己在哪個 Tab,F(xiàn)ooter 中相應的 button 也會從白底黑字黑底白字,與另外兩個 Tab 形成對比。

現(xiàn)在我們來看看 main 部分的代碼(在上面代碼的基礎上擴充):

...

  
    
      
    
  
  
    
  


  
    
      
    
    無數(shù)據(jù)
  
  

...

這里用到了 列表渲染 和 條件渲染,還不清楚的可以點擊進去學習一下。

可以看到,相比之前的代碼,我添加一個 header,同時 main-area 的內部也新增了一個 scroll-view(用于展示 Feed 流) 和一個 button(用于編輯新迷你微博)。header 的功能很簡單:左側區(qū)域是一個 picker,可以選擇查看的動態(tài)類型(目前有 關注動態(tài)所有動態(tài) 兩種);右側區(qū)域是一個按鈕,點擊后可以跳轉到搜索頁面,這兩個功能我們先放一下,先繼續(xù)看 main-area 的新增內容。

main-area 里的 scroll-view 是一個可監(jiān)聽滾動事件的列表,其中監(jiān)聽事件的實現(xiàn):

data: {
  ...
  addPosterBtnBottom: "190rpx",
  mainHeaderMaxHeight: "80rpx",
  mainAreaHeight: "calc(100vh - 200rpx)",
  mainAreaMarginTop: "80rpx",
},
onMainPageScroll: function(e) {
  if (e.detail.deltaY < 0) {
    this.setData({
      addPosterBtnBottom: "-190rpx",
      mainHeaderMaxHeight: "0",
      mainAreaHeight: "calc(100vh - 120rpx)",
      mainAreaMarginTop: "0rpx"
    })
  } else {
    this.setData({
      addPosterBtnBottom: "190rpx",
      mainHeaderMaxHeight: "80rpx",
      mainAreaHeight: "calc(100vh - 200rpx)",
      mainAreaMarginTop: "80rpx"
    })
  }
},
...

結合 wxml 可以知道,當頁面向下滑動 (deltaY < 0) 時,header 和 button 會 “突然消失”,反之它們則會 “突然出現(xiàn)”。為了視覺上有更好地過渡,我們可以在 WXSS 中使用 transition

...
.main-area {
  position: relative;
  flex-grow: 1;
  overflow: auto;
  z-index: 1;
  transition: height 0.3s, margin-top 0.3s;
}
.main-header {
  position: fixed;
  width: 100%;
  height: 80rpx;
  background: #fff;
  top: 0;
  left: 0;
  display: flex;
  justify-content: space-around;
  align-items: center;
  z-index: 100;
  border-bottom: 3rpx solid #aaa;
  transition: max-height 0.3s;
  overflow: hidden;
}
.add-poster-btn {
  position: fixed;
  right: 60rpx;
  box-shadow: 5rpx 5rpx 10rpx #aaa;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #333;
  padding-bottom: 10rpx;
  text-align: center;
  border-radius: 50%;
  font-size: 60rpx;
  width: 100rpx;
  height: 100rpx;
  transition: bottom 0.3s;
  background: #fff;
  z-index: 1;
}
...
3. Feed 流 3.1 post-item

前面提到,scroll-view 的內容是 Feed 流,那么首先就要想到使用 列表渲染。而且,為了方便在個人主頁復用,列表渲染中的每一個 item 都要抽象出來。這時就要使用小程序中的 Custom-Component 功能了。

新建一個名為 post-itemComponent,其中 wxml 的實現(xiàn)(路徑:pages/circle/component/post-item/post-item.js):


  
    {{data.author}}
    {{data.formatDate}}
  
  
    {{data.msg}}
  
  
    
  

可見,一個 poster-item 最主要有以下信息:

作者名

發(fā)送時間

文本內容

圖片內容

其中,圖片內容因為是可選的,所以使用了 條件渲染,這會在沒有圖片信息時不讓圖片顯示區(qū)域占用屏幕空間。另外,圖片內容主要是由 image-wrapper 組成,它也是一個 Custom-Component,主要功能是:

強制長寬 1:1 裁剪顯示圖片

點擊查看大圖

未加載完成時顯示 加載中

具體代碼這里就不展示了,比較簡單,讀者可以在 component/image-wrapper 里找到。

回過頭看 main-area 的其他新增部分,細心的讀者會發(fā)現(xiàn)有這么一句:

無數(shù)據(jù)

這會在 Feed 流暫時沒有獲取到數(shù)據(jù)時給用戶一個提示。

3.2 collections: poster、poster_users

展示 Feed 流的部分已經編寫完畢,現(xiàn)在就差實際數(shù)據(jù)了。根據(jù)上一小節(jié) poster-item 的主要信息,我們可以初步推斷出一條迷你微博在 云數(shù)據(jù)庫 的 collection poster 里是這樣存儲的:

{
  "username": "Tester",
  "date": "2019-07-22 12:00:00",
  "text": "Ceshiwenben",
  "photo": "xxx"
}

先來看 username。由于社交平臺一般不會限制用戶的昵稱,所以如果每條迷你微博都存儲昵稱,那將來每次用戶修改一次昵稱,就要遍歷數(shù)據(jù)庫把所有迷你微博項都改一遍,相當耗費時間,所以我們不如存儲一個 userId,并另外把 id 和 昵稱 的對應關系存在另一個叫 poster_users 的 collection 里。

{
  "userId": "xxx",
  "name": "Tester",
  ...(其他用戶信息)
}

userId 從哪里拿呢?當然是通過之前已經授權的獲取用戶信息接口拿到了,詳細操作之后會說到。

接下來是 date,這里最好是服務器時間(因為客戶端傳過來的時間可能會有誤差),而云開發(fā)文檔里也有提供相應的接口:serverDate。這個數(shù)據(jù)可以直接被 new Date() 使用,可以理解為一個 UTC 時間。

text 即文本信息,直接存儲即可。

photo 則表示附圖數(shù)據(jù),但是限于小程序 image 元素的實現(xiàn),想要顯示一張圖片,要么提供該圖片的 url,要么提供該圖片在 云存儲 的 id,所以這里最佳的實踐是:先把圖片上傳到云存儲里,然后把回調里的文件 id 作為數(shù)據(jù)存儲。

綜上所述,最后 poster 每一項的數(shù)據(jù)結構如下:

{
  "authorId": "xxx",
  "date": "utc-format-date",
  "text": "Ceshiwenben",
  "photoId": "yyy"
}

確定數(shù)據(jù)結構后,我們就可以開始往 collection 添加數(shù)據(jù)了。但是,在此之前,我們還缺少一個重要步驟。

3.3 用戶信息錄入 與 云數(shù)據(jù)庫

沒錯,我們還沒有在 poster_users 里添加一條新用戶的信息。這個步驟一般在 pages/circle/circle 頁面首次加載時判斷即可:

getUserId: function(cb) {
  let that = this
  var value = this.data.userId || wx.getStorageSync("userId")
  if (value) {
    if (cb) {
      cb(value)
    }
    return value
  }
  wx.getSetting({
    success(res) {
      if (res.authSetting["scope.userInfo"]) {
        wx.getUserInfo({
          withCredentials: true,
          success: function(userData) {
            wx.setStorageSync("userId", userData.signature)
            that.setData({
              userId: userData.signature
            })
            db.collection("poster_users")
              .where({
                userId: userData.signature
              })
              .get()
              .then(searchResult => {
                if (searchResult.data.length === 0) {
                  wx.showToast({
                    title: "新用戶錄入中"
                  })
                  db.collection("poster_users")
                    .add({
                      data: {
                        userId: userData.signature,
                        date: db.serverDate(),
                        name: userData.userInfo.nickName,
                        gender: userData.userInfo.gender
                      }
                    })
                    .then(res => {
                      console.log(res)
                      if (res.errMsg === "collection.add:ok") {
                        wx.showToast({
                          title: "錄入完成"
                        })
                        if (cb) cb()
                      }
                    })
                    .catch(err => {
                      wx.showToast({
                        title: "錄入失敗,請稍后重試",
                        image: "/images/error.png"
                      })
                      wx.navigateTo({
                        url: "/pages/index/index"
                      })
                    })
                } else {
                  if (cb) cb()
                }
              })
          }
        })
      } else {
        wx.showToast({
          title: "登陸失效,請重新授權登陸",
          image: "/images/error.png"
        })
        wx.navigateTo({
          url: "/pages/index/index"
        })
      }
    }
  })
}

代碼實現(xiàn)比較復雜,整體思路是這樣的:

判斷是否已存儲了 userId,如果有直接返回并調用回調函數(shù),如果沒有繼續(xù) 2

通過 wx.getSetting 獲取當前設置信息

如果返回里有 res.authSetting["scope.userInfo"] 說明已經授權讀取用戶信息,繼續(xù) 3,沒有授權的話就跳轉回首頁重新授權

調用 wx.getUserInfo 獲取用戶信息,成功后提取出 signature(這是每個微信用戶的唯一簽名),并調用 wx.setStorageSync 將其緩存

調用 db.collection().where().get() ,判斷返回的數(shù)據(jù)是否是空數(shù)組,如果不是說明該用戶已經錄入(注意 where() 中的篩選條件),如果是說明該用戶是新用戶,繼續(xù) 5

提示新用戶錄入中,同時調用 db.collection().add() 來添加用戶信息,最后通過回調判斷是否錄入成功,并提示用戶

不知不覺我們就使用了云開發(fā)中的 云數(shù)據(jù)庫 功能,緊接著我們就要開始使用 云存儲 和 云函數(shù)了!

3.4 addPoster 與 云存儲

發(fā)送新的迷你微博,需要一個編輯新迷你微博的界面,路徑我定為 pages/circle/add-poster/add-poster