国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

微信小程序之小豆瓣圖書實(shí)例

2019-11-19 18:45:14
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

最近微信小程序被炒得很火熱,本人也抱著試一試的態(tài)度下載了微信web開(kāi)發(fā)者工具,開(kāi)發(fā)工具比較簡(jiǎn)潔,功能相對(duì)比較少,個(gè)性化設(shè)置也沒(méi)有。了解完開(kāi)發(fā)工具之后,順便看了一下小程序的官方開(kāi)發(fā)文檔,大概了解了小程序的開(kāi)發(fā)流程和一些常用的API。

了解了小程序之后,自己就有了想要做一個(gè)小demo的沖動(dòng),雖然自己對(duì)小程序還沒(méi)有做過(guò)很多實(shí)踐,只是在官方例子上徘徊,但是還是想做出點(diǎn)小東西。既然要做一個(gè)demo,自然需要到數(shù)據(jù),自己有又不想獨(dú)自搭建服務(wù)端,所以在網(wǎng)上搜索可以用來(lái)提供測(cè)試數(shù)據(jù)的免費(fèi)api,最后我選擇了豆瓣圖書。豆瓣圖書提供的api功能比較少,加上不開(kāi)放appkey申請(qǐng),所以無(wú)法操作用戶數(shù)據(jù)。只能做點(diǎn)簡(jiǎn)單的圖書查詢和圖書詳細(xì)信息展示,這個(gè)demo只有兩個(gè)頁(yè)面,非常之簡(jiǎn)單。

豆瓣圖書API

demo中用到的豆瓣圖書api只有兩個(gè),一個(gè)是圖書搜索,另一個(gè)是獲取圖書詳情。

搜索圖書

GET https://api.douban.com/v2/book/search

參數(shù) 意義 備注
q 查詢關(guān)鍵字 q和tag必傳其一
tag 查詢的tag q和tag必傳其一
start 取結(jié)果的offset 默認(rèn)為0
count 取結(jié)果的條數(shù) 默認(rèn)為20,最大為100

返回status=200

{ "start": 0, "count": 10, "total": 30, "books" : [Book, ...]}

獲取圖書詳情

GET https://api.douban.com/v2/book/:id

參數(shù) 意義
:id 圖書id

以下是具體圖書的詳情信息,部分demo中用不到的信息省略

{  "id":"1003078",  "title":"小王子",  "alt":"https:////book.douban.com//subject//1003078//",  "image":"https://img3.doubanio.com//mpic//s1001902.jpg",  "author":[    "(法)圣埃克蘇佩里"    ],  "publisher":"中國(guó)友誼出版公司",  "pubdate":"2000-9-1",  "rating":{"max":10,"numRaters":9438,"average":"9.1","min":0},  "author_intro":"圣埃克蘇佩里(1900-1944)1900年,瑪雅?戴斯特萊姆......",  "catalog":"序言:法蘭西玫瑰/n小王子/n圣埃克蘇佩里年表/n"}

Demo編寫

創(chuàng)建項(xiàng)目

項(xiàng)目取名為DouBanBookApp,項(xiàng)目的結(jié)構(gòu)小程序默認(rèn)的結(jié)構(gòu)一樣

DouBanBookApp  pages    index 首頁(yè)      index.js      index.wxml      index.wxss    detail 詳情頁(yè)      detail.js      detail.wxml      detail.wxss  requests     api.js API地址    request.js 網(wǎng)絡(luò)請(qǐng)求  utils    util.js 工具  app.js  app.json  app.wxss

應(yīng)用的主調(diào)色參考了豆瓣app的色調(diào),采用了偏綠色。

首頁(yè)

首頁(yè)頂部展示搜索輸入框,用戶輸入圖書名稱,點(diǎn)擊搜索按鈕,展示圖書列表。圖書可能會(huì)很多,不能一下子全部展示,需要用到分頁(yè),app上最常見(jiàn)的列表分頁(yè)就是上拉加載模式,根據(jù)小程序提供的組件中,找到了一個(gè)比較符合場(chǎng)景的scroll-view組件,這個(gè)組件有一個(gè)上拉到底部自動(dòng)觸發(fā)的bindscrolltolower事件。

先制作出界面的靜態(tài)效果,之后再整合API,由于本人對(duì)界面設(shè)計(jì)不敏感,所以隨便弄了一個(gè)粗糙的布局,看得過(guò)去就行了,嘿嘿~~

index.wxml

<view class="search-container"> <input type="text" placeholder="輸入書名搜索"></input><icon type="search" size="20"/></view><scroll-view scroll-y="true" style="width:100%;position:relative;top:40px;height:200px">  <view style="text-align:center;padding-top:50rpx;">   <icon type="cancel" color="red" size="40" />   <view><text>沒(méi)有找到相關(guān)圖書</text></view>  </view>  <view style="text-align:center;padding-top:50rpx;">   <icon type="search" size="60" />   <view><text>豆瓣圖書</text></view>  </view>    <view class="header">   <text>圖書 10本圖書</text>  </view>  <view class="common-list">  <view class="list-item">   <view class="index-list-item">    <view class="cover">     <image class="cover-img" src="images/demo.png"></image>    </view>    <view class="content">     <view class="title">圖書標(biāo)圖</view>     <text class="desc">9.0/oopsguy/2016-07-08</text>    </view>   </view>  </view>  </view>  <view class="refresh-footer">   <icon type="waiting" size="30" color="reed" />  </view></scroll-view>

index.wxss

page { background: #F2F1EE;}/*seach*/.search-container { position: fixed; top: 0; right: 0; left: 0; background-color: #42BD56; color: #FFF; height: 40px; padding: 0 10rpx; z-index: 100;}.search-container input { background: #FFF; color: #AAA; margin-top: 5px; padding: 5px 10rpx; height: 20px; border-radius: 8rpx;}.search-container icon { position: absolute; top: 10px; right: 20rpx;}/*header*/.header { padding: 20rpx 30rpx;}.header text { color: #A6A6A6;}/*common list*/.list-item { position: relative; overflow: hidden}/*index list*/.index-list-item { background: #FFF; padding: 15rpx 30rpx; overflow: hidden;}.index-list-item::active { background: #EEE;}.index-list-item .cover { float: left; width: 120rpx; height: 160rpx; overflow: hidden}.index-list-item .cover image.cover-img { width: 120rpx; height: 160rpx;}.index-list-item .content { margin-left: 140rpx;}.index-list-item .title { display: inline-block; height: 90rpx; padding-top: 20rpx; overflow: hidden;}.index-list-item .desc { display: block; font-size: 30rpx; padding-top: 10rpx; color: #AAA; white-space:nowrap; overflow: hidden; text-overflow: ellipsis;}.refresh-footer { text-align: center; padding: 10rpx 0;}

圖書詳細(xì)頁(yè)面

圖書詳細(xì)頁(yè)面就是展示具體的圖書信息,通用首頁(yè)穿過(guò)了的圖書id來(lái)獲取圖書信息之后在展示出來(lái),獲取的過(guò)程中可能有延遲,需要一個(gè)加載效果來(lái)過(guò)渡。

detail.wxml

<view>  <view class="cover-container">    <image src="images/demo.png"></image>  </view>  <view class="book-meta">    <view class="meta-info">      <text class="book-title">圖書標(biāo)題</text>      <text class="other-meta">作者:作者名稱</text>      <text class="other-meta">出版社:xxx出版社</text>      <text class="other-meta">出版日期:2010-05-07</text>    </view>    <view class="range">      <text class="score">0</text>      <text class="viewers">0</text>    </view>  </view>  <view class="book-intro">    <view class="intro-header"><text>簡(jiǎn)介</text></view>    <text class="intro-content">      這是圖書簡(jiǎn)介    </text>  </view>  <view class="book-intro">    <view class="intro-header"><text>作者</text></view>    <text class="intro-content">      這是作者簡(jiǎn)介    </text>  </view></view><loading>  加載中...</loading>

detail.wxss

page {  background: #EEE;}.cover-container {  background: #42BD56;  text-align: center;  padding: 50rpx 0;}.cover-container image {  display: inline-block;  width: 300rpx;  height: 400rpx;}.book-meta {  position: relative;  padding: 20rpx;  overflow: hidden;}.book-meta .range {  position: absolute;  top: 30rpx;  right: 20rpx;  width: 180rpx;  background: #FFF;  padding: 20rpx 10rpx;  text-align: center;  box-shadow: 2px 2px 10px #CCC;}.book-meta .meta-info {  margin-right: 200rpx;}.meta-info text {  display: block}.book-title {  font-weight: bold;  font-size: 50rpx;}.other-meta {  padding-top: 10rpx;  color: #888;  font-size: 30rpx;}.range text {  display: block;}.range .score {  font-size: 50rpx;  font-weight: bold;}.range .starts {  font-size: 40rpx;}.range .viewers {  font-size: 30rpx;}.book-intro {  padding: 20rpx;  font-size: 40rpx;}.book-intro .intro-header {  color: #888}.book-intro .intro-content {  font-size: 35rpx;  line-height: 45rpx;}

做好了首頁(yè)和詳細(xì)頁(yè)的靜態(tài)頁(yè)面,接下來(lái)就是通過(guò)網(wǎng)絡(luò)請(qǐng)求api來(lái)獲取數(shù)據(jù),并顯示到頁(yè)面上來(lái)。

網(wǎng)絡(luò)請(qǐng)求和數(shù)據(jù)處理

為了更好的管理api,我把a(bǔ)pi專門放到了一個(gè)單獨(dú)的api.js文件中

api.js

const API_BASE = "https://api.douban.com/v2/book";module.exports = { API_BOOK_SEARCH: API_BASE + "/search", API_BOOK_DETAIL: API_BASE + "/:id"}

有些經(jīng)常用到的工具函數(shù)放到了util.js中

util.js

function isFunction( obj ) { return typeof obj === 'function';}module.exports = { isFunction: isFunction}

微信小程序提供了一個(gè)用于網(wǎng)絡(luò)請(qǐng)求的api:wx.request(OBJECT),具體的參數(shù)跟jquery的ajax方法差不多,為了方便調(diào)用,我把網(wǎng)絡(luò)請(qǐng)求放到了request.js中

request.js

var api = require('./api.js');var utils = require('../utils/util.js');/** * 網(wǎng)路請(qǐng)求 */function request(url, data, successCb, errorCb, completeCb) {  wx.request({    url: url,    method: 'GET',    data: data,    success: function(res) {      utils.isFunction(successCb) && successCb(res.data);    },    error: function() {      utils.isFunction(errorCb) && errorCb();    },    complete: function() {      utils.isFunction(completeCb) && completeCb();    }  });} /** * 搜索圖書 */function requestSearchBook(data, successCb, errorCb, completeCb) {  request(api.API_BOOK_SEARCH, data, successCb, errorCb, completeCb);}/** * 獲取圖書詳細(xì)信息 */function requestBookDokDetail(id, data, successCb, errorCb, completeCb) {  request(api.API_BOOK_DETAIL.replace(':id', id), data, successCb, errorCb, completeCb);}module.exports = { requestSearchBook: requestSearchBook, requestBookDokDetail: requestBookDokDetail}

首頁(yè)有圖書搜索和列表展示,上拉加載的效果。微信小程序中沒(méi)有了DOM操作的概念,一切的界面元素的改變都要通過(guò)數(shù)據(jù)變化來(lái)改變,所以需要在js中的Page中的data中聲明很多數(shù)據(jù)成員。

用戶在輸入數(shù)據(jù)時(shí),輸入框的input綁定了searchInputEvent事件,就回捕獲到輸入的數(shù)據(jù),把輸入的數(shù)據(jù)更新的data中的searchKey中。

searchInputEvent: function( e ) {  this.setData( { searchKey: e.detail.value });}

當(dāng)點(diǎn)擊搜索按鈕是,觸發(fā)tap事件,其綁定了searchClickEvent

searchClickEvent: function( e ) {  if( !this.data.searchKey )   return;  this.setData( { pageIndex: 0, pageData: [] });  requestData.call( this );}

requestData中封裝了請(qǐng)求圖書列表的方法

/** * 請(qǐng)求圖書信息 */function requestData() { var _this = this; var q = this.data.searchKey; var start = this.data.pageIndex; this.setData( { loadingMore: true, isInit: false }); updateRefreshBall.call( this ); requests.requestSearchBook( { q: q, start: start }, ( data ) => {  if( data.total == 0 ) {   //沒(méi)有記錄   _this.setData( { totalRecord: 0 });  } else {   _this.setData( {    pageData: _this.data.pageData.concat( data.books ),    pageIndex: start + 1,    totalRecord: data.total   });  } }, () => {  _this.setData( { totalRecord: 0 }); }, () => {  _this.setData( { loadingMore: false }); });}

上拉加載的效果是一個(gè)小球不停的變換顏色,需要一個(gè)顏色列表

//刷新動(dòng)態(tài)球顏色var iconColor = [ '#353535', '#888888'];

然后用一個(gè)定時(shí)器來(lái)動(dòng)態(tài)改變小球圖標(biāo)的顏色

/** * 刷新上拉加載效果變色球 */function updateRefreshBall() { var cIndex = 0; var _this = this; var timer = setInterval( function() {  if( !_this.data[ 'loadingMore' ] ) {   clearInterval( timer );  }  if( cIndex >= iconColor.length )   cIndex = 0;  _this.setData( { footerIconColor: iconColor[ cIndex++ ] }); }, 100 );}

詳細(xì)頁(yè)面的顯示需要到首頁(yè)點(diǎn)擊了具體圖書的id,所以需要首頁(yè)傳值過(guò)來(lái),這里用到了小程序土工的wx.navigateTo方法,給其指定的url參數(shù)后面帶以查詢字符串格式形式的參數(shù),被跳轉(zhuǎn)的頁(yè)面就會(huì)在onLoad方法中得到值。

//跳轉(zhuǎn)到詳細(xì)頁(yè)面toDetailPage: function( e ) {  var bid = e.currentTarget.dataset.bid; //圖書id [data-bid]  wx.navigateTo( {   url: '../detail/detail?id=' + bid  });}

detail.js中接受參數(shù)

onLoad: function( option ) {  this.setData({   id: option.id  });}

其實(shí)小程序的頁(yè)面制作跟平時(shí)的html和css差不多,只是頁(yè)面中不能用傳統(tǒng)的html標(biāo)簽,而是改用了小程序提供的自定義標(biāo)簽,小程序?qū)ss的支持也有限制,注意哪些寫法不兼容也差不多懂了。操作頁(yè)面變化是通過(guò)數(shù)據(jù)變化來(lái)表現(xiàn)出來(lái)的,這點(diǎn)有點(diǎn)像react和vue。以上的demo用到的知識(shí)點(diǎn)并不多,主要是頁(yè)面的數(shù)據(jù)綁定、事件綁定、模版知識(shí)和網(wǎng)絡(luò)請(qǐng)求等相關(guān)api。仔細(xì)看看文檔也差不多可以做出一個(gè)小例子。

最終效果圖

總體來(lái)說(shuō),Demo很簡(jiǎn)單,只有兩個(gè)頁(yè)面,界面也是丑丑的T_T,算是我入門小程序的第一課吧。

示例代碼

源碼地址:demo下載

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 岳普湖县| 肥城市| 富平县| 怀安县| 利津县| 中卫市| 浙江省| 瓦房店市| 松溪县| 佳木斯市| 东辽县| 江永县| 哈密市| 惠州市| 天门市| 陕西省| 奉节县| 湛江市| 九台市| 绩溪县| 高唐县| 博爱县| 固阳县| 开远市| 德江县| 宁远县| 清水河县| 伊宁市| 康马县| 惠州市| 南溪县| 上犹县| 义马市| 驻马店市| 红河县| 镇沅| 浮山县| 屏山县| 平和县| 监利县| 宁陕县|