|
小程序云開(kāi)發(fā)發(fā)布有一段時(shí)間了,最近著手做了一個(gè)基于云開(kāi)發(fā)的小程序項(xiàng)目--仿《微博鮮知》,來(lái)自新浪的這款全新風(fēng)格的小程序雖然界面非常簡(jiǎn)約清新,但是內(nèi)部還是內(nèi)藏了很多玄機(jī),在實(shí)現(xiàn)的路上遇上了不少坎坷,在這里分享給大家。希望給大家提供一些思路。 先展示一下最終結(jié)果: 更多圖片資源在這里
一、 組件化思想開(kāi)發(fā)一個(gè)完整的小程序時(shí),我們應(yīng)該先分析其內(nèi)部的結(jié)構(gòu)。重復(fù)的結(jié)構(gòu)抽離出來(lái)作為組件,組件非常的靈活,可以嵌入一個(gè)頁(yè)面或多個(gè)頁(yè)面。 在上面的gif圖中我們可以看到首頁(yè)的內(nèi)容是一個(gè)個(gè)的新聞塊。 雖然這個(gè)新聞塊只在首頁(yè)中使用到,但是我還是把它抽離成了一個(gè)組件。這樣做的好處是頁(yè)面結(jié)構(gòu)將會(huì)更加的清晰,并且耦合度降低,比如想換個(gè)主界面風(fēng)格時(shí),你可以直接換另一個(gè)組件添加進(jìn)來(lái)。 還有新聞內(nèi)部頁(yè)面中,有多個(gè)小標(biāo)題,每個(gè)小標(biāo)題里面嵌入了不等數(shù)量的新聞。如果不是采用組件化的話,到時(shí)候inner頁(yè)面的wxml結(jié)構(gòu)就會(huì)亂成一鍋粥。所以這里的建議是盡量組件化分離開(kāi)來(lái)。 對(duì)于組件很陌生可以先看我的之前的這篇文章組件化開(kāi)發(fā)tabbar 下面是項(xiàng)目的頁(yè)面與組件目錄:
二、數(shù)據(jù)庫(kù)設(shè)計(jì)既然是“全棧”,后端肯定要搞搞。后端的核心就是數(shù)據(jù)。那么我們就先把數(shù)據(jù)庫(kù)分析一下。這里我是這樣分析的,
這里我構(gòu)建了5個(gè)集合 fresh-mainNews 主頁(yè)新聞集合 subNews字段是一個(gè)數(shù)列,存儲(chǔ)著fresh-subNews Doc的_id,這樣就將這兩個(gè)集合綁定了起來(lái),在后面我們會(huì)講到在云函數(shù)中把這兩個(gè)集合融合起來(lái)返回一個(gè)新的數(shù)據(jù)變得完整一些的集合。 有人可能會(huì)問(wèn),云數(shù)據(jù)庫(kù)不是noSQL嗎,為什么不把所有數(shù)據(jù)全部整合到一個(gè)全部的JSON,那樣就可以只調(diào)用一次JSON。 我的理解是: 我們查詢只是需要查詢我們想要的數(shù)據(jù),不需要的數(shù)據(jù)可以等需要的時(shí)候再根據(jù)關(guān)聯(lián)去請(qǐng)求。 比如這個(gè)項(xiàng)目中的首頁(yè)新聞塊,每一個(gè)新聞塊內(nèi)部都關(guān)聯(lián)著大量的子新聞,第一次加載就全部把這個(gè)小程序需要的所有數(shù)據(jù)都加載出來(lái)就有點(diǎn)瘋狂了。
三、頁(yè)面構(gòu)建講到這里就該說(shuō)頁(yè)面的構(gòu)建了。頁(yè)面可以想象成一個(gè)架子,一個(gè)承載數(shù)據(jù)的容器。頁(yè)面通上數(shù)據(jù),就變得活起來(lái)。MVVM,數(shù)據(jù)驅(qū)動(dòng)視圖。交互靠數(shù)據(jù),組件間的通信,組件與頁(yè)面間的通信都是數(shù)據(jù)。{{}} -> 就像是流浪法師大招神奇的傳送門。后面會(huì)將給出一個(gè)精彩的組件通信例子(點(diǎn)擊目錄如何實(shí)現(xiàn)標(biāo)題欄置頂)。 四、關(guān)于云開(kāi)發(fā)。云開(kāi)發(fā)三大核心: 云函數(shù):通俗的理解就是你寫的函數(shù)在云端運(yùn)行,可以把復(fù)雜的業(yè)務(wù)邏輯放在云函數(shù)里 數(shù)據(jù)庫(kù):一個(gè)既可在小程序前端操作,也能在云函數(shù)中讀寫的 JSON 數(shù)據(jù)庫(kù) 存儲(chǔ):在小程序前端直接上傳/下載云端文件,在云開(kāi)發(fā)控制臺(tái)可視化管理,可以上傳照片下載照片,或者一些其他文件。 在這里詳細(xì)介紹一下操作云函數(shù)提取數(shù)據(jù)庫(kù)的流程, 這里我們以獲取首頁(yè)數(shù)據(jù)為例:
獲取的數(shù)據(jù): 我們可以看到原本的subNews里面本來(lái)存放的是_id的數(shù)值,融合后變成_id對(duì)應(yīng)的整個(gè)doc 變化: [_id1.value,_id2.value~~] ---> [{_id1:value,key1:value1,key2:value2},~~~]
云函數(shù)的調(diào)用,數(shù)據(jù)庫(kù)的查詢。就是這么簡(jiǎn)單的四步,云開(kāi)發(fā)的門檻很低,功能也很強(qiáng)大,只要你去嘗試,很輕松的就能夠?qū)崿F(xiàn)。 五、關(guān)于時(shí)間格式化。
六、 關(guān)于一些很有用但是你可能不知道的小程序技巧
wx.previewImage({
current: imgUrl, // 當(dāng)前顯示圖片的http鏈接
urls: imagePack // 需要預(yù)覽的圖片http鏈接列表
})
復(fù)制代碼
//給數(shù)組設(shè)置值 還可以有var xx = 'xx['+idx+'].key'的形式
var doneList = 'doneList['+idx+']'
that.setData({
[doneList]: true,
})
復(fù)制代碼
有時(shí)候我們還可以先改變某個(gè)數(shù)的值再去setData()它,這是setData()的一個(gè)很好用的技巧,不過(guò)需要去運(yùn)用一下才好理解 如:
dataPack.likeNum = (supLikeNum===-1 ? dataPack.likeNum: supLikeNum);
this.setData({
comment: dataPack,
})
復(fù)制代碼
七、 項(xiàng)目最精彩的兩個(gè)部分1.點(diǎn)擊目錄欄頁(yè)面將相應(yīng)新聞欄置頂,先看下效果
這個(gè)效果在別的小程序里面都沒(méi)有見(jiàn)過(guò),應(yīng)該是微博鮮知獨(dú)創(chuàng)的,在這里先對(duì)原作者表達(dá)一下敬意。內(nèi)部的構(gòu)造也是非常巧妙,不同于我們常見(jiàn)的外賣的錨點(diǎn)定位。 我們先來(lái)分析一波: mvvm,視圖是由數(shù)據(jù)驅(qū)動(dòng)的,我們要透過(guò)現(xiàn)象看本質(zhì),去思考底層的數(shù)據(jù),這樣我們很快就會(huì)有思路:
<block wx:for="{{subNews}}" wx:for-item="subNewsItem" wx:for-index="idx" wx:key="index">
<view class="subTitle-item" bind:tap="scrollFind"
//關(guān)鍵1:綁定item索引
data-hi="{{idx}}">
<text>{{subNewsItem.title}}</text>
</view>
</block>
復(fù)制代碼
onCatalog: function(e) {
e.detail // 自定義組件觸發(fā)事件時(shí)提供的detail對(duì)象
console.log(e.detail.index)
//關(guān)鍵:3 把索引存儲(chǔ)到data
this.setData({
catalogIndex : e.detail.index
})
//關(guān)鍵4: 頁(yè)面可以通過(guò)組件的id取得其頁(yè)面引用組件的方法
// this.subNews=this.selectComponent("#subNews")
this.subNews.goTop();
},
復(fù)制代碼
<subNews ~省略~ catalogIndex="{{catalogIndex}}" id="subNews"></subNews>
復(fù)制代碼
//subNews/index.wxml
//一個(gè)看不見(jiàn)的圖片,來(lái)自瀑布流的靈感,能夠產(chǎn)生主動(dòng)觸發(fā)的事件
<view style="display:none">
<image src="{{mainImg}}" bindload="onImageLoad"></image>
</view>
復(fù)制代碼
goTop: function (e) {
var that = this
let catalogIndex = that.data.catalogIndex;
//這里offsetList是一個(gè)data里面的數(shù)據(jù),來(lái)保存所有的節(jié)點(diǎn)的上邊距坐標(biāo)
let offsetList = that.data.offsetList;
wx.pageScrollTo({
scrollTop: offsetList[catalogIndex], //滾動(dòng)到具體數(shù)值所在的位置
duration: 50 //執(zhí)行滾動(dòng)所花的時(shí)間
})
}
復(fù)制代碼
至此,你就實(shí)現(xiàn)了這個(gè)看似簡(jiǎn)單卻非常巧妙的功能,組件->頁(yè)面->組件,秀得眼花繚亂。如果還是有些不理解的話,等下可以下載我的代碼去看。 至于為什么要弄一個(gè)圖片的加載然后觸發(fā)那個(gè)事件呢,這是因?yàn)槿绻惆勋@取offsetList偏移量數(shù)組的函數(shù)放在goTop里的話,進(jìn)入頁(yè)面第一次的點(diǎn)擊會(huì)無(wú)效,這樣產(chǎn)生的體驗(yàn)肯定是非常不舒服的。 2. 點(diǎn)贊優(yōu)化先展示一下效果:
先說(shuō)一下優(yōu)化的是什么:點(diǎn)贊效果的延遲極大降低 因?yàn)辄c(diǎn)贊的變化是由用戶產(chǎn)生的一個(gè)交互,傳統(tǒng)的觀點(diǎn)就是用戶點(diǎn)贊->后端更新數(shù)據(jù)->前端拉取數(shù)據(jù)->數(shù)據(jù)驅(qū)動(dòng)視圖的變化。 真實(shí)的體驗(yàn)就是,非常的慢,慢到點(diǎn)擊后2秒才能看到點(diǎn)贊的效果,這種差勁的交互簡(jiǎn)直就是一場(chǎng)災(zāi)難。
<text class="dianzanNum">{{likeNumList[idx]?likeNumList[idx]:item.likeNum}}</text>
復(fù)制代碼
優(yōu)化思路是怎么樣的呢? 用一個(gè)數(shù)組來(lái)存放/模擬更新的數(shù)據(jù),如果數(shù)字的索引位置被賦值,則頁(yè)面直接顯示這個(gè)更新的數(shù)字,也是異曲同工之妙。因?yàn)橛脩絷P(guān)心的是數(shù)據(jù)的變化,我們可以先把數(shù)據(jù)的變化產(chǎn)生,至于數(shù)據(jù)后端的變化讓他異步慢慢的去做。 從這里發(fā)散思想,是不是評(píng)論功能也能夠用這樣的思路同樣去達(dá)到極致的速度與交互體驗(yàn)?zāi)亍?/p> 點(diǎn)贊的延遲幾乎為無(wú),體驗(yàn)到點(diǎn)贊的極致快感,讓人幾乎停不下來(lái)~~(暗示一波) 篇幅所限,文章到這里就差不多了。 項(xiàng)目地址: github-HappyBirdwe-weiboFresh 奉上 精心寫的項(xiàng)目,細(xì)節(jié)很不錯(cuò)喲,歡迎大家☆☆☆☆star☆☆☆☆結(jié)語(yǔ): 學(xué)習(xí)的道路上免不了坎坷,希望文章的分享能夠?yàn)榇蠹姨峁┮恍┧悸?,學(xué)習(xí)的過(guò)程減少一點(diǎn)彎路,這就是這篇文章最大的價(jià)值,歡迎大家提問(wèn)及指正。 |