基於Bmob從零開始寫一個部落格小程式
實現以下技能點
1、整合Bmob小程式SDK作為資料儲存
2、wemark解析markdown文字
3、列表頁佈局與上拉無限載入
實現的效果
一、建立Bmob應用
進入Bmob官網:http://bmob.cn/,註冊一個賬號,免費的賬號可以建立8個子應用,每個應用單表列數是20列,如要購買付費,可以分別買100元與1000元檔,詳見官網價目表。
1、建立一個應用
2、檢視它的key資訊以及配置自己小程式的key資訊,如果有支付的,加配支付MchID與key,支付對於付費會員才可用。
4、為小程式新增白名單
在小程式管理後臺,進入設定->開發設定->伺服器域名,為4個域名統一新增地址為api.bmob.cn。
這事實是不對了,真正在填寫的要等小程式報錯時才知道,如下圖
1-2報白名單錯誤.png
於是刪除掉之前的填寫的白名單api.bmob.cn,而使用小程式真正使用到的這個三級域名:4552ad36df85c1f29953ae3679c69248.bmobcloud.com
,小程式以前是1月允許3次修改白名單,目前是1個月允許5次,少走一些彎路可以節省一些次數的。
下圖是我更正後的配置資訊
二、小程式端整合
1、建立小程式專案,appid使用的就是剛剛配置在Bmob後臺的那個appid。
2、開啟app.js引入bmob的js sdk庫,並初始化
var Bmob = require('utils/bmob.js'); Bmob.initialize("你的Application ID", "你的REST API Key");
三、讀取文章列表
由於沒有寫專門的web後臺,於是直接在bmob的後臺視覺化介面錄入
1、建表與欄位
欄位名 | 型別 | 註釋 |
---|---|---|
title | String | 標題 |
content | String | 內容 |
priority | Number | 越大越靠前 |
1-3建表與欄位.png
2、根目錄下新建article目錄,再新建list資料夾,下面放著list.wxml、list.wxss與list.js
1-4目錄結構.png
注意要將剛剛建立的頁面檔案新增到app.json中
{
"pages":[
"article/list/list"
]
}
3、引入bmob.js檔案,讀取所有的文章列表列表
var Bmob = require('../../utils/bmob.js');
var that;
Page({
onLoad: function () {
that = this;
var Article = Bmob.Object.extend("article");
var query = new Bmob.Query(Article);
// 按照priority逆序排列
query.descending('priority');
// 查詢所有資料
query.find({
success: function(results) {
// 請求成功將資料存入article_list
that.setData({
article_list: results
});
},
error: function(error) {
alert("查詢失敗: " + error.code + " " + error.message);
}
});
}
});
定義一個全域性的that變數,以解決非同步請求時作用域改變的問題,以後的每一個方法都使用that以代替this。
4、製作列表頁佈局檔案與樣式
<!-- 遍歷文章列表 -->
<view wx:for="{{article_list}}" class="row" wx:key="">
<!-- 縮圖 -->
<view>
<image src="{{item.thumb}}" class="thumb" mode="aspectFill" />
</view>
<!-- 標題與日期 -->
<view>
<!-- 標題 -->
<view class="title">{{item.title}}</view>
<!-- 日期 -->
<view class="time">{{item.updatedAt}}</view>
</view>
</view>
其中圖片使用了aspectFill模式,保證了圖片不變形且是填充滿<image>
標籤的;且<image>
需要包在<view>
中,不然css設定的寬度無效,僅高度有效。
/*每行行內元素按行分佈*/
.row {
display: flex;
flex-direction: row;
margin: 10px;
}
/*縮圖*/
.thumb {
width: 100px;
height: 75px;
margin-right: 10px;
margin-top: 5px;
}
/*文章標題*/
.title {
font-size: 16px;
color: #333;
margin: 10px 0;
line-height: 130%;
}
/*日期*/
.time {
font-size: 14px;
color: #999;
margin: 10px 0;
}
使用了flex佈局作為左右排列與上下排列的控制。其中縮圖與文字呈左右排列, 標題與日期呈上面排列。
四、列表頁分頁
剛剛實現的列表是讀取的全部,一般來講會有上拉載入的效果,也就是分頁
1、通過skip與limit實現分頁
將請求程式碼獨立出一個成員方法loadArticle(),以方便下拉載入與onLoad載入是共用
loadArticle: function () {
var page_size = 10;
...
// 分頁
query.limit(page_size);
query.skip(that.data.page_index * page_size);
// 查詢所有資料
query.find({
success: function(results) {
// 請求成功將資料存入article_list
that.setData({
article_list: that.data.article_list.concat(results)
});
});
}
使用concat方法將分頁請求得到數組合併入原始陣列,以求不斷迭加。
onReachBottom: function () {
that.setData({
page_index: ++that.data.page_index
});
that.loadArticle();
}
實現onReachBottom方法加page_index不斷加1,使頁碼遞增後,再請求Bmob資料。
2、底部加上載入狀態的文字顯示
頁面上加一個<view>
<view class="loading-indicator">
{{loadingTip}}
</view>
配上樣式
/*上拉載入提示*/
.loading-indicator {
text-align: center;
font-size: 12px;
margin: 10px 0;
}
js檔案如下處理
data: {
loadingTip: '上拉載入更多'
}
宣告好loadingTip資料後,如果本次請求返回的行數小於每頁行數代表是否還有更多資料(粗略的演算法,更合理地做法是多請求一行例如11行,返回不夠數了才是真沒有下一頁了)
// 判斷上拉載入狀態
if (results.length < page_size) {
that.setData({
loadingTip: '沒有更多內容'
});
}
五、製作詳情頁
1、處理帶參跳轉
首先,為.row行新增一個點選事件
<view wx:for="{{article_list}}" class="row" wx:key="" bindtap="showDetail" data-index="{{index}}">
然後,取出wxml繫結的數值,設定跳轉路徑
showDetail: function (e) {
// 獲取wxml元素繫結的index值
var index = e.currentTarget.dataset.index;
// 取出objectId
var objectId = that.data.article_list[index].id;
// 跳轉到詳情頁
wx.navigateTo({
url: '../detail/detail?objectId=' + objectId
});
}
最後,在article目錄建立detail資料夾,除建立同上頁面3個檔案外,再建立一個.json檔案,配置頁面標題欄文字顯示
{
"navigationBarTitleText": "文章詳情"
}
2、detail頁面接收引數
Page({
onLoad: function (options) {
// 獲取傳參
var objectId = options.objectId;
}
})
3、取出文章資料
以objectId為引數,向Bmob請求文詳情資料
var Bmob = require('../../utils/bmob.js');
var that;
Page({
data: {
content: ''
},
onLoad: function (options) {
that = this;
// 獲取傳參
var objectId = options.objectId;
// 向Bmob請求詳情頁資料
var Article = Bmob.Object.extend("article");
//建立查詢物件,入口引數是物件類的例項
var query = new Bmob.Query(Article);
//查詢單條資料,第一個引數是這條資料的objectId值
query.get(objectId, {
success: function(result) {
// 查詢成功,呼叫get方法獲取對應屬性的值
var content = result.get("content");
that.setData({
content: content
});
},
error: function(object, error) {
// 查詢失敗
}
});
}
})
4、渲染頁面
<view class="container">
<view class="title">{{article.title}}</view>
<view class="time">{{article.updatedAt}}</view>
<view class="content">{{article.content}}</view>
</view>
外層包裹一個container是為了設定邊距,美化頁面。
/*外部容器*/
.container {
margin: 20px 10px;
}
/*標題*/
.title {
text-align: center;
color: #333;
font-size: 20px;
margin: 10px 0;
}
/*日期*/
.time {
text-align: center;
color: #999;
font-size: 12px;
margin: 10px 0;
}
/*內容*/
.content {
margin: 20px 0;
font-size: 14px;
color: #555;
line-height: 140%;
}
如此,已經順利獲取到了詳情頁內容並顯示出來了。剩下就是將markdown轉為正常的顯示。
六、利用wemark渲染文章
接下來按照git上的教程整合wemark。
1、wxml引入
<import src="../../wemark/wemark.wxml"/>
<template is="wemark" data="{{...wemark}}"></template>
刪除原來的<view class="content">{{article.content}}</view>
,因為不再用到它了。
2、wxss引入
@import '../../wemark/wemark.wxss'
3、js中引入
var wemark = require('../../wemark/wemark');
然後設定資料
data: {
wemark: {}
},
再在請求Bmob成功回撥里加上
// 渲染markdown
wemark.parse(result.get('content'), that, {
imageWidth: getApp().screenWidth - 20
})
效果如下
這個例子是比較簡單的,但是做複雜的基礎,諸如flex佈局,data儲存,navigate傳值,無限載入,可以說是必然會用到的,對於沒有接觸過小程式開發的朋友應該是有借鑑意義的。