最近本身正作一個小程序,是基於小程序雲開發的,在作小程序項目的時候使用雲開發確實方即是不少。有關於雲開發後面我也會講到,畢竟這個項目就是使用的雲開發,雲開發內容有須要的小夥伴也能夠去看官方文檔, 雲開發文檔。
項目的開發也有一段時間了雖然只是實現了部分功能,可是我仍是忍不住來寫篇文章來分享一下這段時間的成果和項目中遇到的問題,後面我也會逐步的完善項目。項目源碼在github上,若是小夥伴們以爲不錯能夠給個star,仿頭條項目地址。
git
下面將詳細的介紹項目,雖然使用的雲開發節省了不少時間可是先後端的東西都須要作工做量有點大,在這短期內我沒有完成整個項目,只是實現了首頁,詳情頁,和登陸頁等主要功能
我首先將界面須要獲取數據的地方設計好數據庫爲後面數據的獲取作準備,數據庫使用的是小程序雲開發的MongoDB數據庫,將數據存儲在雲數據庫上,而且使用雲函數來操做數據庫github
輸入框綁定了一個tap事件,使得在點擊輸入框但不輸入值的時候改變placeholder的值。
在tab欄的右邊有一個按鈕點擊按鈕將會出現一個彈出層,前面的gif中有演示,是新聞種類的選擇框,點擊關閉按鈕能夠關閉彈出層
最後就是首頁最重要的新聞顯示頁面了,爲了節省項目的時間,這裏使用了有讚的框架vant-weapp有興趣的小夥伴能夠去了解下。在tab標籤欄設置了6個標籤頁,可是隻會顯示4個標籤頁想要顯示其餘的能夠左右拖動標籤欄,這裏將推薦頁設置爲了默認激活的。因爲每一個每一個標籤頁代碼基本都相同的,只是在推薦頁是的第一欄是置頂信息,還有就是獲取的數據不一樣,有關數據獲取在下面介紹代碼將會細講,爲了提升代碼的複用,這裏使用了模板,將複用的代碼寫在寫在另外的文件下,使用時直接調用就能夠了。
每一個標籤對應都建立了一個集合,這裏我爲置頂新聞也另外建立了一個集合,而且給每條信息設計好須要用的字段方便本身獲取數據和使用數據,因爲雲數據庫是能夠導入json文件或者csv文件,而且每一個新聞也都須要上拉加載數據須要更多的數據,本身造數據費時間又麻煩,因此我這裏本身寫了爬蟲爬取本身須要的數據並保存到json文件中,直接將數據導入到數據庫中。
這樣設計數據庫也是使得從數據庫獲取數據方便了一些。寫一個module函數就能夠獲取每一個標籤的數據。
每條數據的字段以下,其中news_id起到很重要的做用,將首頁的每條新聞和對應的詳情頁面聯繫起來。 數據庫
在每個標籤頁使用模板,而且設置了一個data(給不一樣頁面傳入須要顯示的對應新聞信息,用於在頁面顯示),因爲默認激活頁面是推薦頁因此在onload事件觸發時將默認加載推薦頁的數據,同時將推薦頁設置爲已被激活頁面,數據加載這裏寫了一個加載函數json
module: function(title) {
let counter = this.data.counter
// console.log(title)
wx.cloud.callFunction({
name: 'module',
data: {
counter: counter,
title: title
}
}).then(res => {
// console.log(res)
let cnews = this.data.cnews
let data = res.result.data
// console.log(data)
for(let i = 0; i < data.length; i++) {
// console.log(data[i].date)
data[i].date = data[i].date.slice(0, 10)
cnews.push(data[i])
this.imgCheck(data[i].images, data.new_id, title)
}
// console.log(data)
this.setData({
hiddenLoading: true,
cnews: cnews,
counter: counter+1
})
})
}
複製代碼
傳入一個title就是當前顯示的標籤的標題,默認的是推薦,使用一個counter計數,每次只會加載5條新聞條數據,從數據庫獲取新聞的信息是由一個雲函數來解決的小程序
#### 經過雲函數獲取數據
// 雲函數入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
// 雲函數入口函數
exports.main = async (event, context) => {
return await db.collection(event.title).skip((event.counter-1)*5).limit(5).get()
}
複製代碼
給雲函數傳入兩個數據,一個是title就是從對應集合獲取信息,還有一個就是counter用來計算獲取信息的位置,由於,在向上拉取加載更多新聞的時候須要加載數據,我這裏設置每次加載5條數據,因此傳遞給雲函數一個counter,每次調用了雲函數從與數據庫獲取一次數據counter就會+1,從而使得每次上拉加載數據時忽略已經加載的數據從後面加載數據。每次加載數據都會更新一次保存數據的數組,在主頁的index.wxml頁面將會判斷並獲取數據使用一個for循環將數據顯示到對應的標籤頁
後端
在置頂新聞那部分在數據獲取的數據其實也沒很特別,我只是將置頂新聞集合中最新的新聞從雲數據庫拿下來,而後展現頁面中
這裏也實現了下拉刷新,使用了小程序的onPullDownRefresh函數下拉刷新將會獲取最新的數據,而且將最新的數據插顯示在最上部分,因爲每次下拉須要插入數據到集合的前面,因此我這裏顯示不明顯
微信小程序
onPullDownRefresh: function () { // 監聽下拉動做來獲取最新新聞信息
wx.showToast({
title: '推薦中',
image: '../../../image/加載.png'
})
let title = this.data.title;
wx.cloud.callFunction({
name: 'module',
data: {
counter: 1,
title: title
}
}).then(res => {
// console.log(res)
let cnews = this.data.cnews
let datas = res.result.data
let data = datas.concat(cnews)
this.setData({
hiddenLoading: true,
cnews: data,
})
})
}
複製代碼
在module函數有使用了一個圖片鑑黃功能,使用了騰訊的一個圖片識別接口,畢竟不是什麼圖片都能顯示出來,因此寫了一個imgCheck函數來檢測每一條新聞的全部圖片,當圖片不合格的時候則將這條新聞刪除。我沒有使用圖片去測試,更不可能展現出來是吧,相信你們都懂(猥瑣笑)。
當不一樣標籤頁進行切換的時候會有一個onchange事件,onchange事件會得到title和index。而且將onchange以後的數據保存到一個數組中,在onchange事件裏面使用module函數來獲取對應的title的數據而且判斷這條數據是不是最近加載過的,若是是上次onchange事件加載過的函數將會顯示上次事件保存的數據,在wxml中也會判斷是不是上次激活的頁面來顯示對應的數據。
前面一直再講後端的東西,我也這篇文章也是爲了講雲開,說實話有了雲開發真的方便了不少,一我的就能夠搞定先後端的東西。不過爲了方便你們的理解,我仍是講一下界面的內容。
既然前都已經將數據拿過來了,最後要作的就是將數據展現出來了,每條數據數組
<van-tab title="推薦" >
<!-- 推薦tab標籤頁的置頂新聞框 每個新聞框能夠點擊進入到詳情頁-->
<van-panel class="topping" title="{{topTitle}}" status="置頂" use-footer-slot bind:tap="showTopDetail" data-item="{{topNew_id}}">
<view class="images">
<image src="{{images[0]}}" />
<image src="{{images[1]}}" />
<image src="{{images[2]}}" />
</view>
<view solt="footer" class="footer">
<view class="author">{{topAuthor}}</view>
<view class="comment">評論{{topComment}}</view>
<view class="Date">{{topDate}}</view>
</view>
</van-panel>
<template is="container" data="{{news: active1 == 'news'?news:cnews, hiddenLoading}}"></template>
</van-tab>
複製代碼
<template name="container">
<view class="container">
<loading hidden="{{hiddenLoading}}"></loading>
<view class="news" wx:for="{{news}}" wx:for-item="info" wx:key="info.new_id">
<van-panel class="new" title="{{info.title}}" bind:tap="showDetail" use-footer-slot data-item="{{info.new_id}}">
<view class="images" wx:if="{{info.images.length > 0}}">
<image src="{{info.images[0]}}"/>
<image src="{{info.images[1]}}"/>
<image src="{{info.images[2]}}"/>
</view>
<view solt="footer" class="footer">
<view class="author">{{info.author}}</view>
<view class="comment">評論{{info.comments}}</view>
<view class="Date">{{info.date}}</view>
</view>
</van-panel>
</view>
</view>
</template>
複製代碼
這裏用的就是MVVM思想,將數據綁定到UI界面,在js文件中獲取到數據後,這裏將數據拿過來使用。
這裏因爲每條新聞的圖片數量是不肯定的,而且最多隻顯示三張圖片。因此直接固定了3個image標籤而且固定了image的大小,當圖片沒有的時候就不會顯示圖片。bash
不少在首頁講過的東西我在詳情頁也就再也不多說了,你們有不懂能夠去看源碼,畢竟講那麼多廢話就是浪費時間,我儘可能挑出最精彩的部分來寫。 微信
在首頁的每一條新聞都綁定了一個跳轉tap事件,當點擊新聞後將會跳轉到詳情頁,而且將新聞的id和title做爲參數傳給詳情頁。
showDetail: function(e) { // 點文章顯示文章詳情
let item = e.currentTarget.dataset.item;
let title = this.data.title;
// console.log(e)
wx.navigateTo({
url:`../detail/detail?contentId=${item}&title=${title}`
})
}
複製代碼
在點擊跳轉到詳情頁後,將會在onload的事件中獲取到對應的新聞id,並將id存到data裏面。因爲在爬取詳情頁的時候沒有爬下來,因此我隨便將一些簡單的內容放在content裏面。
詳情頁這部分我將頁面分爲了內容部分和評論。而後還有就是使用了一個fixed將輸入框等按鈕固定在屏幕底部
內容部分又分爲了四部分,分別是標題部分,做者頭像和暱稱,內容部分,點贊轉發部分,將數據庫中的數據展現顯示到界面。
第二部分爲顯示像和暱稱我使用了一個flex的浮動佈局將而且將暱稱部分的flex設置爲1使得頭像和關注按鈕分別在兩邊。頭像使用了一個image標籤而且將image標籤的大小固定,畢竟用戶上傳的圖片確定大小不同。第四部分只要使用4個view在把圖片和內容放進去再使用一個flex佈局就能夠搞定。
既然界面佈局已經搞定如今就是要拿數據了,在點擊新聞進入來詳情頁的時候會的到新聞的id和title,這樣能夠經過惟一id(每條doc的id)的和title(集合的名字)從雲數據庫拿出對應新聞數據。這裏代碼就不貼出來了,跟前面首頁的差很少,有須要的能夠去github看源碼。
接下來就是評論部分的內容了,我的認爲這個地方仍是挺有趣並且在更新數據庫的時候還有權限問題,前面沒有講這個問題就是打算放到評論部分一塊兒來說。 在頁面的底部固定了一個評論框,包含輸入框,跳轉到評論的按鈕,收藏按鈕,轉發按鈕。
submit: function() { // 實現評論功能,將發佈的評論同步到雲數據庫
let value = this.data.inputValue;
let new_id = this.data.new_id;
let userInfo = this.data.userInfo
// let new_id = '6594157273642172936'
if(userInfo){
comments.where({
new_id: new_id
}).get({
success: (res) => {
// console.log(res)
let comms= res.data[0].comments;
let people = {
content: value,
like: 0,
avatar: userInfo.avatarUrl,
nickname: userInfo.nickname
}
comms.unshift(people);
// console.log(comm)
this.setData({
comms: comms,
input: '',
})
wx.cloud.callFunction({
name: 'updateComments',
data: {
new_id: new_id,
comms: comms
}
}).then(res =>{
console.log(res)
})
}
})
}
}
複製代碼
評論部分的數據庫我只建立了一個comments集合,開始的新聞new_id就起到做用了,每一comment都有一個new_id,新聞的每一條評論就是設置爲一個對象,畢竟評論還包括頭像暱稱,點贊數,評論內容等。這樣設置評論數據庫好處就是,只要獲取新聞id在一個集合中就能夠獲取到新聞對應的評論。
addLike: function(e) { // 點擊點贊圖標增長點贊數同時保存到數據庫
let item = e.currentTarget.dataset.item;
let new_id = this.data.new_id;
let comms = this.data.comms;
let likeItem = this.data.likeItem;
let likebool = 'likeItem['+item+'].bool'
let liken = 'likeItem['+item+'].n'
if(typeof(likeItem[item]) == "undefined"){
this.setData({
[likebool]: false,
[liken]: 0,
})
}
if(likeItem[item]){
likeItem[item].n += 1;
if(likeItem[item].n%2){
comms[item].like += 1;
}else{
comms[item].like -= 1;
}
likeItem[item].bool = !(likeItem[item].bool);
}else{
likeItem[item].bool = true;
likeItem[item].n = 0;
comms[item].like += 1;
}
this.setData({
comms: comms,
likeItem: likeItem
})
// console.log(comms)
wx.cloud.callFunction({
name: 'updateComments',
data: {
new_id: new_id,
comms: comms
}
}).then(res =>{
// console.log(res)
})
},
複製代碼
在評論輸入框的下邊欄有一個複選框按鈕,圖片按鈕等這裏我使用了了flex佈局輕鬆搞定,這是我實現了下評論插入圖片功能,同時將圖片保存到雲端。其實評論插入圖片還須要優化,我在寫完文章後也還會繼續優化。 我這是使用了小程序雲開發的一個文件上傳接口wx.cloud.uploadFile,將圖片上傳後會生成一個fileID,我將fileID(也就是圖片地址)保存到當前評論對象的image下,同時更新本地的數據,再經過一個if來判斷當前的評論是否含有圖片,有的話就將圖片顯示在評論中。這裏代碼我就不貼出來,有須要的能夠看源碼。
因爲項目有點大因此我在短期內只實現了部分功能,在後續的時間我會實現其餘功能。其實寫這個項目也是爲了實戰雲開發,同時我也體驗到了雲開發的好處。項目中有些不足的地方歡迎你們指出,有什麼好的建議也能夠聯繫我。你們相互學習