日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

小程序·云开发实战 - 迷你微博

發(fā)布時間:2023/12/10 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小程序·云开发实战 - 迷你微博 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0. 前言

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

  • Feed 流:關注動態(tài)、所有動態(tài)
  • 發(fā)送圖文動態(tài)
  • 搜索用戶
  • 關注系統(tǒng)
  • 點贊動態(tài)
  • 個人主頁

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

  • 云數據庫
  • 云存儲
  • 云函數
  • 云調用

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

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

1. 取得授權

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

<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">進入小圈圈 </button>

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

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

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

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

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

2. 主頁設計

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

  • Feed 流
  • 消息
  • 個人信息

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

<view class="circle-container"><viewstyle="display:{{currentPage === 'main' ? 'block' : 'none'}}"class="main-area"></view><viewstyle="display:{{currentPage === 'msg' ? 'flex' : 'none'}}"class="msg-area"></view><viewstyle="display:{{currentPage === 'me' ? 'flex' : 'none'}}"class="me-area"></view><view class="footer"><view class="footer-item"><buttonclass="footer-btn"bindtap="onPageMainTap"style="background: {{currentPage === 'main' ? '#111' : 'rgba(0,0,0,0)'}}; color: {{currentPage === 'main' ? '#fff' : '#000'}}">首頁</button></view><view class="footer-item"><buttonclass="footer-btn"bindtap="onPageMsgTap"style="background: {{currentPage === 'msg' ? '#111' : 'rgba(0,0,0,0)'}}; color: {{currentPage === 'msg' ? '#fff' : '#000'}}">消息</button></view><view class="footer-item"><buttonclass="footer-btn"bindtap="onPageMeTap"style="background: {{currentPage === 'me' ? '#111' : 'rgba(0,0,0,0)'}}; color: {{currentPage === 'me' ? '#fff' : '#000'}}">個人</button></view></view> </view>

很好理解,畫面主要被分為上下兩個部分:上面的部分是主要內容,下面的部分是三個 Tab 組成的 Footer。重點 WXSS 實現(完整的 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ā)現有一個 currentPage 的 data ,這個 data 的作用其實很直觀:通過判斷它的值是 main/msg/me 中的哪一個來決定主要內容。同時,為了讓首次使用的用戶知道自己在哪個 Tab,Footer 中相應的 button 也會從白底黑字黑底白字,與另外兩個 Tab 形成對比。

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

... <viewclass="main-header"style="display:{{currentPage === 'main' ? 'flex' : 'none'}};max-height:{{mainHeaderMaxHeight}}" ><view class="group-picker-wrapper"><pickerbindchange="bindGroupPickerChange"value="{{groupArrayIndex}}"range="{{groupArray}}"class="group-picker"><button class="group-picker-inner">{{groupArray[groupArrayIndex]}}</button></picker></view><view class="search-btn-wrapper"><button class="search-btn" bindtap="onSearchTap">搜索用戶</button></view> </view> <viewclass="main-area"style="display:{{currentPage === 'main' ? 'block' : 'none'}};height: {{mainAreaHeight}};margin-top:{{mainAreaMarginTop}}" ><scroll-view scroll-y class="main-area-scroll" bindscroll="onMainPageScroll"><blockwx:for="{{pageMainData}}"wx:for-index="idx"wx:for-item="itemName"wx:key="_id"><post-item is="post-item" data="{{itemName}}" class="post-item-wrapper" /></block><view wx:if="{{pageMainData.length === 0}}" class="item-placeholder">無數據</view></scroll-view><buttonclass="add-poster-btn"bindtap="onAddPosterTap"hover-class="add-poster-btn-hover"style="bottom:{{addPosterBtnBottom}}">+</button> </view> ...

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

可以看到,相比之前的代碼,我添加一個 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)聽事件的實現:

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 會 “突然消失”,反之它們則會 “突然出現”。為了視覺上有更好地過渡,我們可以在 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-item 的 Component,其中 wxml 的實現(路徑:pages/circle/component/post-item/post-item.js):

<viewclass="post-item"hover-class="post-item-hover"bindlongpress="onItemLongTap"bindtap="onItemTap" ><view class="post-title"><view class="author" hover-class="author-hover" catchtap="onAuthorTap">{{data.author}}</view><view class="date">{{data.formatDate}}</view></view><view class="msg-wrapper"><text class="msg">{{data.msg}}</text></view><view class="image-outer" wx:if="{{data.photoId !== ''}}" catchtap="onImgTap"><image-wrapper is="image-wrapper" src="{{data.photoId}}" /></view> </view>

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

  • 作者名
  • 發(fā)送時間
  • 文本內容
  • 圖片內容

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

  • 強制長寬 1:1 裁剪顯示圖片
  • 點擊查看大圖
  • 未加載完成時顯示 加載中

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

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

<view wx:if="{{pageMainData.length === 0}}" class="item-placeholder">無數據</view >

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

3.2 collections: poster、poster_users

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

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

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

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

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

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

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

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

綜上所述,最后 poster 每一項的數據結構如下:

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

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

3.3 用戶信息錄入 與 云數據庫

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

getUserId: function(cb) {let that = thisvar 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"})}}}) }

代碼實現比較復雜,整體思路是這樣的:

  • 判斷是否已存儲了 userId,如果有直接返回并調用回調函數,如果沒有繼續(xù) 2
  • 通過 wx.getSetting 獲取當前設置信息
  • 如果返回里有 res.authSetting["scope.userInfo"] 說明已經授權讀取用戶信息,繼續(xù) 3,沒有授權的話就跳轉回首頁重新授權
  • 調用 wx.getUserInfo 獲取用戶信息,成功后提取出 signature(這是每個微信用戶的唯一簽名),并調用 wx.setStorageSync 將其緩存
  • 調用 db.collection().where().get() ,判斷返回的數據是否是空數組,如果不是說明該用戶已經錄入(注意 where() 中的篩選條件),如果是說明該用戶是新用戶,繼續(xù) 5
  • 提示新用戶錄入中,同時調用 db.collection().add() 來添加用戶信息,最后通過回調判斷是否錄入成功,并提示用戶
  • 不知不覺我們就使用了云開發(fā)中的 云數據庫 功能,緊接著我們就要開始使用 云存儲 和 云函數了!

    3.4 addPoster 與 云存儲

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

    <view class="app-poster-container"><view class="body"><view class="text-area-wrapper"><textarea bindinput="bindTextInput" placeholder="在此填寫" value="{{text}}" auto-focus="true" /><view class="text-area-footer"><text>{{remainLen}}/140</text></view></view><view bindtap="onImageTap" class="image-area"><view class="image-outer"><image-wrapper is="image-wrapper" src="{{imageSrc}}" placeholder="選擇圖片上傳" /></view></view></view><view class="footer"><button class="footer-btn" bindtap="onSendTap">發(fā)送</button></view> </view>

    wxml 的代碼很好理解:textarea 顯示編輯文本,image-wrapper 顯示需要上傳的圖片,最下面是一個發(fā)送的 button。其中,圖片編輯區(qū)域的 bindtap 事件實現:

    onImageTap: function() {let that = thiswx.chooseImage({count: 1,success: function(res) {const tempFilePaths = res.tempFilePathsthat.setData({imageSrc: tempFilePaths[0]})}}) }

    直接通過 wx.chooseImage 官方 API 獲取本地圖片的臨時路徑即可。而當發(fā)送按鈕點擊后,會有如下代碼被執(zhí)行:

    onSendTap: function() {if (this.data.text === "" && this.data.imageSrc === "") {wx.showModal({title: "錯誤",content: "不能發(fā)送空內容",showCancel: false,confirmText: "好的"})return}const that = thiswx.showLoading({title: "發(fā)送中",mask: true})const imageSrc = this.data.imageSrcif (imageSrc !== "") {const finalPath = imageSrc.replace("//", "/").replace(":", "")wx.cloud.uploadFile({cloudPath: finalPath,filePath: imageSrc // 文件路徑}).then(res => {that.sendToDb(res.fileID)}).catch(error => {that.onSendFail()})} else {that.sendToDb()} }, sendToDb: function(fileId = "") {const that = thisconst posterData = {authorId: that.data.userId,msg: that.data.text,photoId: fileId,date: db.serverDate()}db.collection("poster").add({data: {...posterData}}).then(res => {wx.showToast({title: "發(fā)送成功"})wx.navigateBack({delta: 1})}).catch(error => {that.onSendFail()}).finally(wx.hideLoading()) }
  • 首先判斷文本和圖片內容是否都為空,如果是則不執(zhí)行發(fā)送,如果不是繼續(xù) 2
  • 提示發(fā)送中,上傳圖片到云存儲,注意需要將圖片中的臨時 url 的一些特殊字符組合替換一下,原因見 文件名命名限制
  • 上傳成功后,調用 db.collection().add(),發(fā)送成功后退回上一頁(即首頁),如果失敗則執(zhí)行 onSendFail 函數,后者見源碼,邏輯較簡單這里不贅述
  • 于是,我們就這樣創(chuàng)建了第一條迷你微博。接下來就讓它在 Feed 流中顯示吧!

    3.5 云函數 getMainPageData

    這個函數的主要作用如前所述,就是通過處理云數據庫中的數據,將最終數據返回給客戶端,后者將數據可視化給用戶。我們先做一個初步版本,因為現在 poster_users 中只有一條數據,所以僅先展示自己的迷你微博。getMainPageData 云函數代碼如下:

    // 云函數入口文件 const cloud = require("wx-server-sdk") cloud.init() const db = cloud.database()// 云函數入口函數 exports.main = async (event, context, cb) => {// 通過 event 獲取入參const userId = event.userIdlet followingResultlet users// idNameMap 負責存儲 userId 和 name 的映射關系let idNameMap = {}let followingIds = []// 獲取用戶信息followingResult = await db.collection("poster_users").where({userId: userId}).get()users = followingResult.datafollowingIds = users.map(u => {return u.userId})users.map(u => {idNameMap[u.userId] = u.name})// 獲取動態(tài)const postResult = await db.collection("poster").orderBy("date", "desc").where({// 通過高級篩選功能篩選出符合條件的 userIdauthorId: db.command.in(followingIds)}).get()const postData = postResult.data// 向返回的數據添加 存儲用戶昵稱的 author 屬性、存儲格式化后的時間的 formatDate 屬性postData.map(p => {p.author = idNameMap[p.authorId]p.formatDate = new Date(p.date).toLocaleDateString("zh-Hans", options)})return postData }

    最后在 pages/circle/circle.js 里補充云調用:

    getMainPageData: function(userId) {const that = thiswx.cloud.callFunction({name: "getMainPageData",data: {userId: userId,isEveryOne: that.data.groupArrayIndex === 0 ? false : true}}).then(res => {that.setData({pageMainData: res.result,pageMainLoaded: true})}).catch(err => {wx.showToast({title: "獲取動態(tài)失敗",image: "/images/error.png"})wx.hideLoading()}) }

    即可展示 Feed 流數據給用戶。

    之后,getMainPageData 還會根據使用場景的不同,新增了查詢所有用戶動態(tài)、查詢關注用戶動態(tài)的功能,但是原理是一樣的,看源碼可以輕易理解,后續(xù)就不再說明。

    4. 關注系統(tǒng)

    上一節(jié)中我們一口氣把云開發(fā)中的大部分主要功能:云數據庫、云存儲、云函數、云調用都用了一遍,接下來其他功能的實現也基本都依賴它們。

    4.1 poster_user_follows

    首先我們需要建一個新的 collection poster_user_follows,其中的每一項數據的數據結構如下:

    {"followerId": "xxx","followingId": "xxx" }

    很簡單,followerId 表示關注人,followingId 表示被關注人。

    4.2 user-data 頁面

    關注或者取消關注需要進入他人的個人主頁操作,我們在 pages/circle/user-data/user-data.wxml 中放一個 user-info 的自定義組件,然后新建該組件編輯:

    <view class="user-info"><view class="info-item" hover-class="info-item-hover">用戶名: {{userName}}</view><view class="info-item" hover-class="info-item-hover" bindtap="onPosterCountTap">動態(tài)數: {{posterCount}}</view><view class="info-item" hover-class="info-item-hover" bindtap="onFollowingCountTap">關注數: {{followingCount}}</view><view class="info-item" hover-class="info-item-hover" bindtap="onFollowerCountTap">粉絲數: {{followerCount}}</view><view class="info-item" hover-class="info-item-hover" wx:if="{{originId && originId !== '' && originId !== userId}}"><button bindtap="onFollowTap">{{followText}}</button></view> </view>

    這里注意條件渲染的 button:如果當前訪問個人主頁的用戶 id (originId) 和 被訪問的用戶 id (userId)的值是相等的話,這個按鈕就不會被渲染(自己不能關注/取消關注自己)。

    我們重點看下 onFollowTap 的實現:

    onFollowTap: function() {const that = this// 判斷當前關注狀態(tài)if (this.data.isFollow) {wx.showLoading({title: "操作中",mask: true})wx.cloud.callFunction({name: "cancelFollowing",data: {followerId: this.properties.originId,followingId: this.properties.userId}}).then(res => {wx.showToast({title: "取消關注成功"})that.setData({isFollow: false,followText: "關注"})}).catch(error => {wx.showToast({title: "取消關注失敗",image: "/images/error.png"})}).finally(wx.hideLoading())} else if (this.data.isFollow !== undefined) {wx.showLoading({title: "操作中",mask: true})const data = {followerId: this.properties.originId,followingId: this.properties.userId}db.collection("poster_user_follows").add({data: {...data}}).then(res => {wx.showToast({title: "關注成功"})that.setData({isFollow: true,followText: "取消關注"})}).catch(error => {wx.showToast({title: "關注失敗",image: "/images/error.png"})}).finally(wx.hideLoading())}} }

    這里讀者可能會有疑問:為什么關注的時候直接調用 db.collection().add() 即可,而取消關注卻要調用云函數呢?這里涉及到云數據庫的設計問題:刪除多個數據的操作,或者說刪除使用 where 篩選的數據,只能在服務端執(zhí)行。如果確實想在客戶端刪除,則在查詢用戶關系時,將唯一標識數據的 _id 用 setData 存下來,之后再使用 db.collection().doc(_id).delete() 刪除即可。這兩種實現方式讀者可自行選擇。當然,還有一種實現是不實際刪除數據,只是加個 isDelete 字段標記一下。

    查詢用戶關系的實現很簡單,云函數的實現方式如下:

    // 云函數入口文件 const cloud = require('wx-server-sdk') cloud.init() const db = cloud.database()// 云函數入口函數 exports.main = async(event, context) => {const followingResult = await db.collection("poster_user_follows").where({followingId: event.followingId,followerId: event.followerId}).get()return followingResult }

    客戶端只要檢查返回的數據長度是否大于 0 即可。

    另外附上 user-data 頁面其他數據的獲取云函數實現:

    // 云函數入口文件 const cloud = require("wx-server-sdk") cloud.init() const db = cloud.database()async function getPosterCount(userId) {return {value: (await db.collection("poster").where({authorId: userId}).count()).total,key: "posterCount"} }async function getFollowingCount(userId) {return {value: (await db.collection("poster_user_follows").where({followerId: userId}).count()).total,key: "followingCount"} }async function getFollowerCount(userId) {return {value: (await db.collection("poster_user_follows").where({followingId: userId}).count()).total,key: "followerCount"} }async function getUserName(userId) {return {value: (await db.collection("poster_users").where({userId: userId}).get()).data[0].name,key: "userName"} }// 云函數入口函數 exports.main = async (event, context) => {const userId = event.userIdconst tasks = []tasks.push(getPosterCount(userId))tasks.push(getFollowerCount(userId))tasks.push(getFollowingCount(userId))tasks.push(getUserName(userId))const allData = await Promise.all(tasks)const finalData = {}allData.map(d => {finalData[d.key] = d.value})return finalData }

    很好理解,客戶端獲取返回后直接使用即可。

    5. 搜索頁面

    這部分其實很好實現。關鍵的搜索函數實現如下:

    // 云函數入口文件 const cloud = require('wx-server-sdk') cloud.init() const db = cloud.database()const MAX_LIMIT = 100 async function getDbData(dbName, whereObj) {const totalCountsData = await db.collection(dbName).where(whereObj).count()const total = totalCountsData.totalconst batch = Math.ceil(total / 100)const tasks = []for (let i = 0; i < batch; i++) {const promise = db.collection(dbName).where(whereObj).skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()tasks.push(promise)}const rrr = await Promise.all(tasks)if (rrr.length !== 0) {return rrr.reduce((acc, cur) => {return {data: acc.data.concat(cur.data),errMsg: acc.errMsg}})} else {return {data: [],errMsg: "empty"}} }// 云函數入口函數 exports.main = async (event, context) => {const text = event.textconst data = await getDbData("poster_users", {name: {$regex: text}})return data }

    這里參考了官網所推薦的分頁檢索數據庫數據的實現(因為搜索結果可能有很多),篩選條件則是正則模糊匹配關鍵字。

    搜索頁面的源碼路徑是 pages/circle/search-user/search-user,實現了點擊搜索結果項跳轉到對應項的用戶的 user-data 頁面,建議直接閱讀源碼理解。

    6. 其他擴展

    6.1 poster_likes 與 點贊

    由于轉發(fā)、評論、點贊的原理基本相同,所以這里只介紹點贊功能如何編寫,另外兩個功能讀者可以自行實現。

    毫無疑問我們需要新建一個 collection poster_likes,其中每一項的數據結構如下:

    {"posterId": "xxx","likeId": "xxx" }

    這里的 posterId 就是 poster collection 里每條記錄的 _id 值,likeId 就是 poster_users 里的 userId 了。

    然后我們擴展一下 poster-item 的實現:

    <view class="post-item" hover-class="post-item-hover" bindlongpress="onItemLongTap" bindtap="onItemTap">...<view class="interact-area"><view class="interact-item"><button class="interact-btn" catchtap="onLikeTap" style="color:{{liked ? '#55aaff' : '#000'}}">贊 {{likeCount}}</button></view></view> </view>

    即,新增一個 interact-area,其中 onLikeTap 實現如下:

    onLikeTap: function() {if (!this.properties.originId) returnconst that = thisif (this.data.liked) {wx.showLoading({title: "操作中",mask: true})wx.cloud.callFunction({name: "cancelLiked",data: {posterId: this.properties.data._id,likeId: this.properties.originId}}).then(res => {wx.showToast({title: "取消成功"})that.refreshLike()that.triggerEvent('likeEvent');}).catch(error => {wx.showToast({title: "取消失敗",image: "/images/error.png"})}).finally(wx.hideLoading())} else {wx.showLoading({title: "操作中",mask: true})db.collection("poster_likes").add({data: {posterId: this.properties.data._id,likeId: this.properties.originId}}).then(res => {wx.showToast({title: "已贊"})that.refreshLike()that.triggerEvent('likeEvent');}).catch(error => {wx.showToast({title: "贊失敗",image: "/images/error.png"})}).finally(wx.hideLoading())}}

    細心的讀者會發(fā)現這和關注功能原理幾乎是一樣的。

    6.2 數據刷新

    我們可以使用很多方式讓主頁面刷新數據:

    onShow: function() {wx.showLoading({title: "加載中",mask: true})const that = thisfunction cb(userId) {that.refreshMainPageData(userId)that.refreshMePageData(userId)}this.getUserId(cb) }

    第一種是利用 onShow 方法:它會在頁面每次從后臺轉到前臺展示時調用,這個時候我們就能刷新頁面數據(包括 Feed 流和個人信息)。但是這個時候用戶信息可能會丟失,所以我們需要在 getUserId 里判斷,并將刷新數據的函數們整合起來,作為回調函數。

    第二種是讓用戶手動刷新:

    onPageMainTap: function() {if (this.data.currentPage === "main") {this.refreshMainPageData()}this.setData({currentPage: "main"}) }

    如圖所示,當目前頁面是 Feed 流時,如果再次點擊 首頁 Tab,就會強制刷新數據。

    第三種是關聯數據變更觸發(fā)刷新,比如動態(tài)類型選擇、刪除了一條動態(tài)以后觸發(fā)數據的刷新。這種可以直接看源碼學習。

    6.3 首次加載等待

    當用戶第一次進入主頁面時,我們如果想在 Feed 流和個人信息都加載好了再允許用戶操作,應該如何實現?

    如果是類似 Vue 或者 React 的框架,我們很容易就能想到屬性監(jiān)控,如 watch、useEffect 等等,但是小程序目前 Page 并沒有提供屬性監(jiān)控功能,怎么辦?

    除了自己實現,還有一個方法就是利用 Component 的 observers,它和上面提到的屬性監(jiān)控功能差不多。雖然官網文檔對其說明比較少,但摸索了一番還是能用來監(jiān)控的。

    首先我們來新建一個 Component 叫 abstract-load,具體實現如下:

    // pages/circle/component/abstract-load.js Component({properties: {pageMainLoaded: {type: Boolean,value: false},pageMeLoaded: {type: Boolean,value: false}},observers: {"pageMainLoaded, pageMeLoaded": function (pageMainLoaded, pageMeLoaded) {if (pageMainLoaded && pageMeLoaded) {this.triggerEvent("allLoadEvent")}}} })

    然后在 pages/circle/circle.wxml 中添加一行:

    <abstract-load is="abstract-load" pageMainLoaded="{{pageMainLoaded}}" pageMeLoaded="{{pageMeLoaded}}" bind:allLoadEvent="onAllLoad" />

    最后實現 onAllLoad 函數即可。

    另外,像這種沒有實際展示數據的 Component,建議在項目中都用 abstract 開頭來命名。

    6.4 scroll-view 在 iOS 的 bug

    如果讀者使用 iOS 系統(tǒng)調試這個小程序,可能會發(fā)現 Feed 流比較短的時候,滾動 scroll-view header 和 button 會有鬼畜的上下抖動現象,這是因為 iOS 自己實現的 WebView 對于滾動視圖有回彈的效果,而該效果也會觸發(fā)滾動事件。

    對于這個 bug,官方人員也表示暫時無法修復,只能先忍一忍了。

    6.5 關于消息 Tab

    讀者可能會疑惑我為什么沒有講解消息 Tab 以及消息提醒的實現。首先是因為源碼沒有這個實現,其次是我覺得目前云開發(fā)所提供的能力實現主動提醒比較麻煩(除了輪詢想不到其他辦法)。

    希望未來云開發(fā)可以提供 數據庫長連接監(jiān)控 的功能,這樣通過訂閱者模式可以很輕松地獲取到數據更新的狀態(tài),主動提醒也就更容易實現了。到那時我可能會再更新相關源碼。

    6.6 關于云函數耗時

    讀者可能會發(fā)現我有一個叫 benchmark 的云函數,這個函數只是做了個查詢數據庫的操作,目的在于計算查詢耗時。

    詭異的是,我前天在調試的時候,發(fā)現查詢一次需要1秒鐘,而寫這篇文章時卻不到100ms。建議在一些需要多次操作數據庫的函數配置里,把超時時間設置長一點吧。目前云函數的性能不太穩(wěn)定。

    7. 結語

    那么關于迷你版微博開發(fā)實戰(zhàn)介紹就到此為止了,更多資料可以直接下載源碼查看哦。

    源碼鏈接

    https://github.com/TencentCloudBase/Good-practice-tutorial-recommended


    如果你有關于使用云開發(fā)CloudBase相關的技術故事/技術實戰(zhàn)經驗想要跟大家分享,歡迎留言聯系我們哦~比心!

    轉載于:https://www.cnblogs.com/CloudBase/p/11236608.html

    總結

    以上是生活随笔為你收集整理的小程序·云开发实战 - 迷你微博的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    国产 成人 久久 | 成人18视频| 亚洲精品麻豆视频 | 97超碰超碰久久福利超碰 | 97视频精品 | 国产剧情一区二区 | 国产在线观看一区 | 日韩一区视频在线 | 国产精品9999 | 日韩精品中字 | 在线免费观看黄色大片 | 日韩网站在线免费观看 | 国产精品一区专区欧美日韩 | 在线观看亚洲精品 | 日韩国产高清在线 | 日韩欧美在线观看一区 | 69视频在线播放 | 欧美精彩视频在线观看 | 去看片| 日韩欧美国产成人 | 色www永久免费 | 在线欧美日韩 | 久久精品日产第一区二区三区乱码 | 日韩成人精品一区二区 | 久久久久国产精品免费 | 男女激情片在线观看 | 男女激情麻豆 | 99久久久久国产精品免费 | 欧美性久久久久久 | 中文字幕一区2区3区 | 91丨九色丨高潮丰满 | 精品国产视频在线 | 亚洲精品久久久蜜桃直播 | 色综合久久久久 | 一区二区三区四区在线 | 东方av在线免费观看 | 亚洲在线视频播放 | 天天躁天天狠天天透 | 免费在线观看一区 | 日韩欧美高清在线观看 | 91免费观看国产 | 久久一区二区三区日韩 | 天天操天天干天天插 | 久久精品4 | 伊人天天狠天天添日日拍 | 国产视频在线一区二区 | 日韩中文三级 | 国产伦精品一区二区三区高清 | 97在线观看免费视频 | 国产精品国产亚洲精品看不卡15 | 操操色 | 中文字幕免费在线 | 五月婷香蕉久色在线看 | 久久伊人热 | 黄色片视频在线观看 | 夜色资源站国产www在线视频 | 精品久久亚洲 | 午夜视频在线观看网站 | 视频在线观看亚洲 | 欧美另类亚洲 | 亚洲天堂网站视频 | 91中文字幕在线 | 亚洲激情电影在线 | 四虎永久免费 | 六月天综合网 | 国产三级在线播放 | 最近日本mv字幕免费观看 | 高清日韩一区二区 | 免费观看av | 精品亚洲男同gayvideo网站 | 日韩色爱 | 在线蜜桃视频 | 亚洲传媒在线 | 手机在线免费av | 超碰日韩 | 视频国产在线观看18 | 国产高清99| 狠狠色伊人亚洲综合网站色 | 国产成人333kkk | 亚洲欧洲精品一区二区精品久久久 | 国产91精品看黄网站 | 999久久久免费精品国产 | 九九九在线| 国产精品视频 | 色噜噜狠狠色综合中国 | 九九热精品视频在线播放 | 狠狠干夜夜操 | 综合网天天色 | 久久久久免费精品视频 | 91最新网址在线观看 | 国产精品私拍 | 国产 欧美 在线 | 成人午夜在线电影 | 亚洲国产精品视频在线观看 | 亚洲美女精品区人人人人 | 波多野结衣一区二区三区中文字幕 | 国产成人一区二区啪在线观看 | 天堂在线v | 精品五月天 | 国产一区二区三区免费视频 | 超碰在线人 | 日本美女xx | 亚洲一级二级三级 | 午夜视频99 | 99电影| 成人av电影免费在线观看 | 奇米影视四色8888 | 一本一本久久a久久精品综合小说 | 国产精品一区久久久久 | 九九久久精品 | 精品国产视频在线观看 | 日韩欧美在线免费观看 | 精品一区二区在线看 | 久久综合加勒比 | 美女国产免费 | 色婷婷综合成人av | 久久免费在线视频 | 亚洲婷婷综合色高清在线 | 久久艹久久 | 毛片永久免费 | 国产在线观看国语版免费 | www.国产在线观看 | 99爱爱| 久久天天躁狠狠躁夜夜不卡公司 | 久久精品电影 | 91中文在线观看 | 久久中文字幕在线视频 | 日韩国产精品一区 | 成人小视频在线 | 久久激情电影 | 五月开心激情网 | 精品国产乱码一区二区三区在线 | 国产成人精品av在线 | 久久系列 | 最近中文字幕免费视频 | 日韩成人在线免费观看 | 久久夜av | 免费美女久久99 | 国产精品影音先锋 | 精品免费久久久久久 | 国产偷v国产偷∨精品视频 在线草 | 久久国内免费视频 | 日韩剧| 国产精品永久免费在线 | a天堂在线看 | 免费观看日韩av | 草免费视频| 九九热在线视频 | 午夜性盈盈 | www91在线观看 | 国产精品视频你懂的 | 中文字幕在线播放av | 天天操天天操天天 | 瑞典xxxx性hd极品 | 欧美一进一出抽搐大尺度视频 | 精品国产一区二区三区四区在线观看 | 97色婷婷| 久免费 | 欧美成人精品三级在线观看播放 | 日韩激情av在线 | 97视频网站 | 国产精品系列在线播放 | 日韩av手机在线看 | 国产精品久久久久av福利动漫 | 中文字幕在线免费 | 亚洲激情在线观看 | 精品人妖videos欧美人妖 | 久久久久久久看片 | 青草草在线视频 | 手机在线欧美 | 亚洲精品xxxx | 成人亚洲精品国产www | 91久色蝌蚪| 国产免费又爽又刺激在线观看 | a成人v在线 | 国产精品久久久久久久久久久免费看 | 久久第四色 | 91成人亚洲 | 涩涩网站在线 | 亚洲日本在线一区 | 精品欧美乱码久久久久久 | 99免在线观看免费视频高清 | 欧美激情视频一二三区 | 美女免费视频网站 | 操久久网| 日韩欧美在线观看 | se婷婷 | 色在线观看网站 | 天天干天天干天天干天天干天天干天天干 | 精品国产免费人成在线观看 | 久久免费在线视频 | 91九色蝌蚪在线 | 国产四虎在线 | 精品国产伦一区二区三区观看说明 | 高清av中文在线字幕观看1 | 五月婷婷在线观看 | 2019av在线视频 | 99热99| 国产很黄很色的视频 | 日韩欧美视频 | 日韩精品免费一区二区三区 | 91禁看片| www.av在线播放 | 久久资源总站 | 成人av电影免费 | 久久久久日本精品一区二区三区 | 国产精品一区二区免费在线观看 | 99热这里只有精品免费 | 国产成人91 | 在线免费视频一区 | 99热在线观看免费 | 狠狠躁日日躁狂躁夜夜躁 | 免费在线播放av电影 | 一区二区理论片 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 精品国产一区二区三区久久久久久 | 久草在线观 | 国产九九精品 | 色香天天| 99色| 在线观看中文字幕网站 | 欧美性色网站 | 久草在线资源网 | 成人av免费播放 | 亚洲激情在线 | 亚洲精品高清在线 | 国际精品久久久久 | 婷婷五月情 | 蜜桃视频成人在线观看 | 99久久999久久久精玫瑰 | 国产精品一区二区久久久久 | av电影免费看 | 夜夜骑首页 | 国产色 在线 | 亚洲精品国产自产拍在线观看 | 日韩欧美综合在线视频 | 久久久久伦理电影 | 日本久草电影 | 日韩精品极品视频 | 91精品国产亚洲 | 久久久久免费视频 | 成人黄色大片网站 | 免费国产一区二区视频 | 亚洲视频在线免费看 | 91尤物国产尤物福利在线播放 | 九九久久久久久久久激情 | 欧美精品一区二区蜜臀亚洲 | 久久久久久久久久久久电影 | 天天天天干| 中文字幕综合在线 | 美女视频是黄的免费观看 | 中文字幕在线观看免费 | 亚洲影音先锋 | 日本精品一区二区 | 不卡av在线播放 | 一区二区三区动漫 | 成人国产精品久久久 | 天天色天天色 | 一区二区三区在线电影 | aaa亚洲精品一二三区 | 免费看网站在线 | 久热免费| 国产91亚洲 | 91在线免费视频 | www.在线观看视频 | 中文字幕永久 | 久久精品国产99国产 | 狠狠色丁香婷婷综合久久片 | 在线激情网 | 日韩在线观看三区 | 黄色app网站在线观看 | 激情在线五月天 | 日产av在线播放 | 久久日本视频 | 青春草免费视频 | 国产在线观看,日本 | 中文字幕av电影下载 | 爱色av.com | 久久伦理 | 九九热在线精品视频 | 日本激情动作片免费看 | 波多野结衣电影一区 | 国产在线探花 | 国产色拍 | 国产一区二区免费看 | 在线免费高清一区二区三区 | 97超在线 | 久草在线视频网 | 精品国产乱码久久久久久1区2匹 | 日韩天堂在线观看 | 欧美日韩国产一区二 | 天天操夜夜曰 | 国产精品一区二区在线观看免费 | 天天操夜夜操 | 一区二区丝袜 | 国产成人黄色网址 | 69av在线播放| 中文字幕免费高清在线 | 高清视频一区二区三区 | 成年免费在线视频 | 成人网大片 | 久久九九精品 | 国产日韩亚洲 | 999久久久欧美日韩黑人 | 久久国产免费看 | 西西www4444大胆在线 | 日韩理论电影在线观看 | av中文字幕在线免费观看 | 色婷婷在线视频 | 18久久久 | 日韩亚洲国产中文字幕 | 久草综合视频 | 日韩欧美一区二区三区在线观看 | 手机在线小视频 | 久久久久久久久久久久久国产精品 | 国产精品高潮呻吟久久久久 | 国产视频在线播放 | 国产精品美女久久久久久久久久久 | www最近高清中文国语在线观看 | 在线www色 | 欧美性黑人 | 在线成人中文字幕 | 天天操天天能 | 色诱亚洲精品久久久久久 | 一级黄网 | 麻豆视频一区二区 | 亚洲女在线 | 国产精品大片免费观看 | 久久精品久久99 | 午夜久久福利 | 国产成人精品久久久久蜜臀 | 午夜三级影院 | 中文在线字幕观看电影 | av 一区二区三区四区 | 中文字幕乱码日本亚洲一区二区 | 亚洲精品网站在线 | 一区二区三区国产精品 | 日本bbbb摸bbbb| 一区二区久久久久 | 久久精品7| 日韩电影中文字幕在线观看 | 激情综合亚洲精品 | 国产成人免费观看久久久 | 人人爽久久涩噜噜噜网站 | 国产一区高清在线观看 | 久久视频二区 | 正在播放久久 | 国产护士av | 国产一级片直播 | 97视频亚洲 | 99久久国产免费免费 | 在线免费精品视频 | 悠悠av资源片 | 99久久精品无免国产免费 | 一区二区三区免费看 | 国产视频一区在线免费观看 | 欧美久久久久久久久久久久久 | 久久精品8| 国产精品久久艹 | 国产成人精品亚洲精品 | 免费中文字幕在线观看 | 蜜桃av综合网| 久久免费99精品久久久久久 | 成人久久影院 | 伊人首页| 日韩免费在线视频观看 | 亚洲视频精品 | 国产一区电影在线观看 | 中文av在线免费观看 | 免费网址你懂的 | 欧美精品久久久久性色 | 九九热免费观看 | 久久激五月天综合精品 | 天天躁天天躁天天躁婷 | 国产在线欧美日韩 | a精品视频 | 最近中文字幕国语免费高清6 | 91九色porny在线 | 中文字幕在线观看视频一区 | 九九九热精品 | 国产精品久久久一区二区三区网站 | 天堂网av 在线 | 国产成人av电影在线观看 | 欧美成年人在线视频 | 国产亚洲视频在线观看 | 91最新在线视频 | 亚洲高清在线 | 99久免费精品视频在线观看 | 丝袜精品视频 | 久久综合狠狠综合 | 狠狠操天天操 | 很污的网站 | 狠狠干干| 视频在线亚洲 | 9999在线观看 | 日韩最新中文字幕 | 国产精品99久久久久久久久久久久 | 黄色资源在线观看 | 夜色成人av| 91精品久久久久久粉嫩 | 成人动态视频 | 国产视频一区精品 | 亚洲性视频 | 久久久久久久久久久影院 | 日韩三级视频在线观看 | 日韩国产欧美在线视频 | 91手机视频在线 | 国产亚洲一区二区三区 | 在线播放av网址 | 黄色精品网站 | 韩国精品视频在线观看 | 亚洲精品在线观看不卡 | 2019精品手机国产品在线 | www.com.黄| 亚洲国产中文字幕在线观看 | 人人超碰免费 | 特级西西444www大胆高清无视频 | 久久久久北条麻妃免费看 | 欧美日韩精品久久久 | 九色最新网址 | 中文永久字幕 | 黄色软件在线看 | 久久综合丁香 | 久久久免费少妇 | 中文字幕二区三区 | 97超碰资源| 97天天综合网 | 亚洲va在线va天堂va偷拍 | 国产精品自产拍在线观看中文 | 蜜臀av性久久久久蜜臀av | 亚洲日本韩国一区二区 | 美女网站视频色 | 亚洲国产精品久久久 | 国产一级91| 日韩大陆欧美高清视频区 | 国产精品久久久久久久毛片 | 色婷婷www| 久久久久黄色 | 欧美日韩高清 | 色综合中文字幕 | 综合激情 | 西西人体4444www高清视频 | 中文字幕av专区 | 丁香婷五月 | 7777xxxx| 免费视频久久久久 | 日本公妇在线观看 | 日韩中文字幕免费视频 | 久久 精品一区 | 人人爽人人澡人人添人人人人 | 国产精品美女999 | 国产欧美最新羞羞视频在线观看 | 国产黄色精品 | 亚洲精品在线观看免费 | 亚洲国产精品影院 | 日韩精品中文字幕在线不卡尤物 | 天天色播 | 亚洲视频久久久久 | 国产亚洲综合精品 | 五月综合激情婷婷 | 日韩手机视频 | 成x99人av在线www | 91av视频| 中文字幕 第二区 | 人人躁 | 中文字幕电影高清在线观看 | 精品久久五月天 | 中文字幕久久精品亚洲乱码 | 99性视频 | 亚洲精品456在线播放 | 国产色女 | 五月天av在线 | 91亚色免费视频 | 精品国产一区二区在线 | 中字幕视频在线永久在线观看免费 | 福利视频导航网址 | 欧美日韩一区二区在线观看 | 婷婷综合电影 | 91视频在线国产 | 免费h漫在线观看 | 欧美一级片免费在线观看 | 中文字幕日韩有码 | 久久午夜精品影院一区 | 免费看一及片 | 亚洲国产大片 | 久久精视频| 久久久免费电影 | 黄色av电影一级片 | 免费看日韩 | 水蜜桃亚洲一二三四在线 | 另类五月激情 | 五月婷婷影院 | 亚洲人人av | 中文永久字幕 | 国产成人精品一区在线 | 日韩久久一区 | 九九热免费在线视频 | 日韩精品久久久免费观看夜色 | av在线在线| 成人免费视频网站 | 中文字幕国产在线 | 亚洲国产精品成人va在线观看 | 一区免费视频 | 亚洲不卡av一区二区三区 | 97在线视频网站 | 欧美一级电影免费观看 | www.com久久 | 国产一区在线播放 | 91私密视频 | 中文字幕一区二区三区在线视频 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 色噜噜噜噜| 婷婷色综合色 | 精品视频免费久久久看 | 日韩免费高清在线观看 | 国产精品久久久久9999 | 九九导航 | 亚洲激精日韩激精欧美精品 | 欧美激情片在线观看 | 黄色日本片 | 97国产电影 | 久久成人欧美 | 99c视频高清免费观看 | 欧美精品成人在线 | 日本夜夜草视频网站 | 午夜狠狠干 | 亚洲一区二区三区精品在线观看 | 超碰激情在线 | 久草精品视频在线观看 | 樱空桃av | 欧美日韩18| 99久久夜色精品国产亚洲96 | 久久天天躁夜夜躁狠狠躁2022 | 超碰在线成人 | 精品久久五月天 | 久久久久国产精品厨房 | 黄色不卡av | 毛片99| a午夜在线 | 国产精品麻豆一区二区三区 | 69av国产| 欧美一区二区三区在线播放 | 日韩在线播放av | 国产小视频网站 | 欧美一区二区在线免费观看 | 香蕉在线视频播放网站 | 久草视频在线资源站 | 成人黄在线 | 久久国内精品视频 | 91精品爽啪蜜夜国产在线播放 | 81精品国产乱码久久久久久 | 亚洲乱亚洲乱亚洲 | 亚洲精品网页 | 欧美日韩国产一二三区 | 久久免费黄色 | 国产精品视频一二三 | 日日夜夜操操操操 | 精品自拍网 | 免费看网站在线 | 亚洲波多野结衣 | 久久人人爽人人爽人人 | 一区二区三区四区精品视频 | 成人中文字幕在线 | 丝袜网站在线观看 | sesese图片| 国产成人精品免费在线观看 | 久久久天堂 | 免费一级片在线 | 夜夜操综合网 | 日日操日日干 | 成人av中文字幕在线观看 | 日本三级中文字幕在线观看 | 精品在线不卡 | 亚洲 欧美 日韩 综合 | 99九九视频| 天天射射天天 | 免费日韩一区二区三区 | 怡红院av久久久久久久 | 97超碰在线免费 | 91欧美国产 | 伊人久久精品久久亚洲一区 | 正在播放一区 | 久久99精品久久久久久清纯直播 | 成人免费视频免费观看 | 在线免费看黄网站 | 午夜丁香视频在线观看 | 欧美久久成人 | 黄色小网站在线观看 | 日韩不卡高清视频 | 亚洲全部视频 | www.xxx.性狂虐 | 美女黄濒| 久久高清av | 国产一在线精品一区在线观看 | 国产精品一区久久久久 | 久久99精品一区二区三区三区 | 亚洲综合精品在线 | 国内外成人免费在线视频 | www178ccom视频在线 | 久久免费视频网站 | 黄网站色成年免费观看 | 久久午夜网 | 中文字幕一区二区三区四区 | 国产丝袜网站 | 久久久久久久久影视 | 婷婷激情在线 | 在线看v片 | 日韩理论在线播放 | 久久99精品久久久久婷婷 | 久热爱 | 美女精品 | 久草免费看 | 国产手机视频精品 | av在线专区 | 久久精品这里精品 | 毛片一区二区 | 国内成人av | 日本中文字幕在线视频 | 麻豆视频观看 | 超碰97久久| 精品国产一区二区三区在线观看 | 亚洲综合激情小说 | 日韩在线免费小视频 | 国产精品99视频 | 俺要去色综合狠狠 | a天堂在线看 | 蜜桃视频日韩 | 久久只精品99品免费久23小说 | 国产一区二区三区高清播放 | 一级性视频| 97av视频在线观看 | 五月婷婷激情网 | 久久国产影院 | 激情视频免费在线观看 | 国产免费大片 | 深爱激情久久 | 一级欧美日韩 | 娇妻呻吟一区二区三区 | 成人福利在线 | 99久久99精品 | 青春草免费在线视频 | 色天天综合网 | 香蕉视频在线播放 | www久久精品 | 五月综合久久 | 国产91精品看黄网站 | 婷婷色站 | 麻豆小视频在线观看 | 久久久网 | 亚洲专区视频在线观看 | 不卡的av在线播放 | 天天se天天cao天天干 | 九九视频精品在线 | 在线播放亚洲 | 久久综合狠狠综合久久综合88 | 韩国av三级| 国产91精品高清一区二区三区 | 日韩中文字幕亚洲一区二区va在线 | 91av在| 久久久久久久国产精品视频 | 国产一区二区不卡视频 | 免费av大全 | av不卡中文字幕 | 深爱激情av | 国产精品18久久久久白浆 | 高清精品久久 | 91看片成人 | 午夜精品久久久久久 | 婷婷激情影院 | 中文字幕亚洲不卡 | 亚洲日本精品视频 | 亚洲成人网在线 | 在线看片中文字幕 | 日韩国产欧美在线视频 | 国内精品视频久久 | 日韩三级.com| 久草免费在线视频观看 | 91电影福利 | 国产黄色免费在线观看 | 97av视频| 中文字幕一区二 | 青青河边草免费直播 | 又黄又刺激 | 在线免费精品视频 | 婷婷爱五月天 | 国产尤物在线视频 | 久草网视频 | 国产免费三级在线观看 | 国产亚洲人成网站在线观看 | 99免费在线观看 | 亚洲a色 | 国产成人在线网站 | 国产亚洲精品久久久网站好莱 | 欧美精品一区二区在线播放 | 国产第一二区 | 久久久久免费精品国产小说色大师 | 在线观看久久久久久 | av在线一 | 国产日韩欧美综合在线 | 日韩美女av在线 | 狠狠地日 | 91av视频在线观看 | 九九九在线观看 | 中文字幕字幕中文 | 国产精品成久久久久 | 91影视成人| 亚洲国产av精品毛片鲁大师 | 欧美日韩免费视频 | 免费福利片 | 国产麻豆视频在线观看 | 国产精品精品久久久久久 | 亚洲高清视频在线观看 | 天天色天天上天天操 | 国产成人精品av在线 | 国产在线理论片 | 久久久久北条麻妃免费看 | 在线精品在线 | av福利免费 | 国产69精品久久99的直播节目 | 在线播放 日韩专区 | 日韩一级黄色av | 国产精品视频久久久 | 午夜精品视频免费在线观看 | 开心激情五月网 | av三级av | 久草网站在线观看 | 久久精品一区二区三 | 午夜私人影院 | 日韩电影中文,亚洲精品乱码 | 久草在线观看视频免费 | 欧美专区亚洲专区 | 成年人在线观看免费视频 | av天天澡天天爽天天av | 国产精品av免费在线观看 | 九热在线| 国产亚洲小视频 | 日韩在线激情 | 国产高清不卡一区二区三区 | 综合黄色网 | 97高清免费视频 | 日韩中文字幕视频在线观看 | 日韩久久精品一区二区三区 | 99 色| 8090yy亚洲精品久久 | 成人毛片久久 | 美女av在线免费 | 欧美一区影院 | 激情视频二区 | 国产一级精品绿帽视频 | 久久免费看毛片 | 在线视频欧美日韩 | 在线播放精品一区二区三区 | 国产精品毛片一区 | 免费的黄色的网站 | 免费一级片视频 | 亚洲专区欧美专区 | 久久综合偷偷噜噜噜色 | 黄色av大片 | 欧美日韩色婷婷 | 成人午夜电影在线 | 日韩视频免费播放 | 高清日韩一区二区 | 欧美黄污视频 | 国产在线不卡精品 | 亚洲v精品 | 亚洲伦理电影在线 | 五月激情久久久 | 欧美a级一区二区 | 国产美女被啪进深处喷白浆视频 | 国产群p视频 | 激情视频二区 | 99久久影院 | 中文字幕文字幕一区二区 | 国产精品99久久久精品 | 亚洲乱码在线 | 亚洲成年人免费网站 | av看片网址 | 六月丁香伊人 | 四虎在线观看网址 | 久久96国产精品久久99漫画 | 男女拍拍免费视频 | 日韩欧美在线综合网 | 在线岛国av| 日韩av快播电影网 | 国产青春久久久国产毛片 | 视频国产在线 | 亚洲精品在线观 | 国产精品99在线播放 | 91精品伦理 | 久久精品一区 | 97热久久免费频精品99 | 九九久久久 | 美女免费黄网站 | 超级碰碰碰免费视频 | 成人午夜毛片 | 久久久毛片 | 黄网站免费大全入口 | 在线观看91精品视频 | 日韩性片 | 久久久国产高清 | 97超碰在线播放 | 欧美成人xxxx | 91精品久久久久久综合乱菊 | 天堂av免费看 | 成人一级视频在线观看 | 狠狠干夜夜爽 | 日韩中文字幕网站 | 国产一级视频 | 丁香视频五月 | 中文字幕日韩高清 | 黄色h在线观看 | 欧美精品久久久久久久亚洲调教 | 国产剧情av在线播放 | 91在线视频在线观看 | 在线观看黄色国产 | 国产视频在线观看一区二区 | 97久久久免费福利网址 | 91一区啪爱嗯打偷拍欧美 | 中文字幕成人在线 | 在线欧美最极品的av | 国产成人久久精品77777 | 天天干夜夜爽 | 欧美久久成人 | 在线成人高清电影 | 天天操夜夜干 | 特级毛片网 | 国产精品一区二区三区久久 | 久久久久激情视频 | 国产在线观看你懂的 | av激情五月| 成人app在线免费观看 | 国产亚洲一级高清 | 国产一区二区三区高清播放 | 久久在线观看 | 久久精品中文字幕免费mv | 狠狠搞,com | 不卡视频一区二区三区 | 久久精品波多野结衣 | 黄色aaa级片 | 日韩一区二区三免费高清在线观看 | 欧美午夜性生活 | 日韩成人免费电影 | 亚洲精品综合欧美二区变态 | 亚洲精品在线视频观看 | 一级理论片在线观看 | 国产99久久精品一区二区永久免费 | 久久精品草 | 亚洲永久精品在线观看 | 91热这里只有精品 | 久草在线观看 | 国产亚洲人成网站在线观看 | 国产精品久久久久亚洲影视 | 另类老妇性bbwbbw高清 | 全久久久久久久久久久电影 | 九九免费精品视频 | 久久综合久久综合这里只有精品 | 亚洲日本va中文字幕 | 91欧美在线| 操少妇视频 | 黄色小说免费观看 | 中文av网站 | 不卡的av电影在线观看 | 日本黄色特级片 | 91在线影院| 国产精品一区二区精品视频免费看 | 色综合色综合色综合 | 国产一二三在线视频 | 五月天国产精品 | 欧美日韩免费视频 | 精品99免费视频 | 91自拍视频在线观看 | av在观看 | 久久在现视频 | 午夜三级福利 | 亚洲理论在线观看电影 | 日韩av一区在线观看 | 国产91成人在在线播放 | 国产精品久久电影观看 | 韩国三级在线一区 | 欧美激情精品久久久久久免费印度 | 黄网站免费大全入口 | 成人在线视频论坛 | 97视频免费在线观看 | 国产精品黄 | 国产精品福利在线播放 | sesese图片 | 日本中文字幕一二区观 | 国产精品高潮呻吟久久av无 | 日韩a在线看 | www.狠狠插.com | 日韩高清免费在线观看 | 黄色一区三区 | 欧美日韩高清一区二区 国产亚洲免费看 | 中文有码在线视频 | 亚洲1区 在线 | 亚洲电影影音先锋 | 开心色插 | 免费麻豆视频 | 国产亚洲视频在线观看 | 久久这里精品视频 | 免费av福利| 国内外激情视频 | 天堂av观看| 日日草天天草 | 国产精品第2页 | 精品夜夜嗨av一区二区三区 | 久久小视频 | 日韩一区二区免费在线观看 | 久产久精国产品 | 色视频在线免费 | 国产精品免费在线播放 | 五月天婷婷免费视频 | 97国产精品亚洲精品 | 又粗又长又大又爽又黄少妇毛片 | 日日干夜夜爱 | 三级视频国产 | 日日噜噜噜噜夜夜爽亚洲精品 | 成人毛片在线观看视频 | 黄色一级大片免费看 | 精品中文字幕在线播放 | 97在线视频免费观看 | 国产网红在线观看 | 中文字幕在线观看的网站 | 黄色一级大片免费看 | 毛片在线网 | 狠狠操天天操 | 美女在线免费观看视频 | 91传媒91久久久| 久久久久五月 | 免费高清av在线看 | 国产韩国精品一区二区三区 | 亚洲黄色软件 | 天天av在线播放 | 亚洲午夜精品一区二区三区电影院 | 丰满少妇在线观看 | 免费看三级黄色片 | 日韩欧美亚州 | 久久乐九色婷婷综合色狠狠182 | 国产精品久久久久久久久久久久久久 | 国产免费一区二区三区网站免费 | 中文字幕资源网在线观看 | 黄色小网站免费看 | 国产精品免费在线播放 | 亚洲国产欧美在线看片xxoo | 99热在线精品观看 | 日韩啪啪小视频 | 国产精品久久久久高潮 | 丁香5月婷婷 | 国产视频一区精品 | 久久91久久久久麻豆精品 | www.91国产 | 国产精品永久在线 | 美女网站视频色 | 能在线观看的日韩av | 精品国产一区二区三区不卡 | 视频在线99re| 欧美人牲| 2021国产精品视频 | av在线播放免费 | 天天插天天干天天操 | av永久网址 | 亚洲国产精品久久久久久 | 久草在线手机观看 | 91网页版在线观看 | 久久国产成人午夜av影院潦草 | 国产婷婷在线观看 | 狠狠色免费| 日韩欧美中文 | 久久一本综合 | 色网址99 | 日本三级中文字幕在线观看 | 国产九色在线播放九色 | 五月婷婷毛片 | 欧美最猛性xxxxx(亚洲精品) | 一区二区三区免费在线播放 | 一级淫片在线观看 | 久久夜靖品 | 欧美日韩视频在线观看一区二区 | 久久婷婷激情 | 午夜精品久久久久久久久久久 | 国产精品一区二 | 亚洲精品美女在线观看播放 | 国产亚洲亚洲 | 天天激情综合网 | 亚洲h视频在线 | 天天操天天舔天天干 | 亚洲日本va在线观看 | 国产福利电影网址 | 视频国产一区二区三区 | 91精品视频网站 | 91麻豆精品国产午夜天堂 | 国产福利精品一区二区 | 国产色视频 | 国产精品九九九 | 国产精品刺激对白麻豆99 | 国产98色在线 | 日韩 | 久草视频在线免费看 | 成片免费观看视频 |