文章目錄
一、首頁API對接
1.新建src\api\index.js
import {get} from '../utils/request'
const API_URL = 'https://test.youbaobao.xyz:18081'
export function getHomeData(params) {
return get(`${API_URL}/book/home/v2`, params)
}
2.在src\pages\index\index.vue創建getHomeData方法
import {getHomeData} from '../../api'
export default {
...
methods: {
getHomeData() {
getHomeData({openId: '1234'}).then(response => {
console.log(response)
})
},
...
試用:
export default {
...
mounted() {
console.log(this.getHomeData())
},
...
3.初始化首頁用到的數據
data() {
return {
hotSearch: '',
shelf: [],
banner: {},
recommend: [],
freeRead: [],
hotBook: [],
category: []
}
},
4.修改src\utils\request.js中的get方法
export function get(url, params = {}) {
const fly = createFly()
if (fly) {
return new Promise((resolve, reject) => {
fly.get(url, params).then(response => {
console.log(response)
if (response && response.data && response.data.error_code === 0) {
resolve(response)
} else {
reject(response)
}
}).catch(err => {
handleError(err)
reject(err)
})
})
}
}
這樣就更符合我們所要請求的數據格式
5.解構請求回來的數據
methods: {
getHomeData() {
getHomeData({openId: '1234'}).then(response => {
const {
data: {
hotSearch: {
keyword
},
shelf,
banner,
recommend,
freeRead,
hotBook,
category,
shelfCount
}
} = response.data
console.log(keyword, shelf, banner, recommend, freeRead, hotBook, category, shelfCount)
this.hotSearch = keyword
this.homeCard = {
bookList: shelf,
num: shelfCount,
userInfo: {
avatar: 'https://www.youbaobao.xyz/mpvue-res/logo.jpg',
nickname: '米老鼠'
}
}
this.banner = banner
this.recommend = recommend
this.freeRead = freeRead
this.hotBook = hotBook
this.category = category
})
},
...
二、搜索和圖書卡片組件數據對接
1.向src\pages\index\index.vue的HomeCard傳入數據
<HomeCard :data="homeCard"/>
2.修改src\components\home\HomeCard.vue的如下部分
<template>
<div class="home-card">
<div class="home-card-inner">
<div class="user-info">
<div class="avatar-wrapper">
<ImageView :src="avatar" round />
</div>
<div class="nickname">{{nickname}}</div>
<div class="shelf-text">書架共有{{num}}本好書</div>
<div class="round-item"></div>
<div class="shelf-text">特別精選</div>
</div>
<div class="book-info">
<div class="book-wrapper">
<div class="book-img-wrapper"
v-for="(item, index) in bookList" :key="index"
@click="onBookClick"
>
<ImageView
:src="item.cover"
/>
</div>
</div>
<div class="shelf-wrapper">
<div class="shelf">書架</div>
<van-icon
class="arrow"
name="arrow"
size="11px"
color="#828489"
></van-icon>
</div>
</div>
<div class="feedback-wrapper"></div>
<div class="feedback-text" @click="onFeedBackClick">反饋</div>
</div>
<van-dialog id="van-dialog"></van-dialog>
</div>
</template>
<script>
import ImageView from '../base/ImageView'
import Dialog from 'vant-weapp/dist/dialog/dialog'
export default {
components: {ImageView},
props: {
data: Object,
hasSign: {
type: Boolean,
default: false
},
signDay: {
type: Number,
default: 0
}
},
computed: {
avatar() {
return this.data && this.data.userInfo && this.data.userInfo.avatar
},
nickname() {
return this.data && this.data.userInfo && this.data.userInfo.nickname
},
num() {
return this.data && this.data.userInfo && this.data.num
},
bookList() {
return (this.data && this.data.bookList) || []
}
},
methods: {
gotoShelf() {
},
onBookClick() {
this.$emit('onClick')
},
sign() {
},
onFeedBackClick() {
Dialog.confirm({
title: '反饋',
message: '您是否確認提交反饋信息?',
confirmButtonText: '是',
cancelButtonText: '否'
}).then(() => {
console.log('點擊是之後的事件')
}).catch(() => {
console.log('點擊否之後的事件')
})
}
}
}
</script>
注意:經過初始化的數據在渲染時需要從計算屬性中拿數據,否則仍爲初始數據
三、圖書推薦組件數據對接
src\pages\index\index.vue
<HomeBook
title="爲你推薦"
:row="1"
:col="3"
:data="recommend"
mode="col"
btn-text="換一批"
@onMoreClick="onBookMoreClick"
@onBookClick="onHomeBookClick"/>
<HomeBook
title="免費閱讀"
:row="2"
:col="2"
:data="freeRead"
mode="row"
btn-text="換一批"
@onMoreClick="onBookMoreClick"
@onBookClick="onHomeBookClick"/>
<HomeBook
title="當前最熱"
:row="1"
:col="4"
:data="hotBook"
mode="col"
btn-text="換一批"
@onMoreClick="onBookMoreClick"
@onBookClick="onHomeBookClick"/>
<HomeBook
title="圖書分類"
:row="2"
:col="2"
:data="category"
mode="category"
btn-text="查看全部"
@onMoreClick="onBookMoreClick"
@onBookClick="onHomeBookClick"/>
四、API請求異常捕獲方法
修改src\utils\request.js的get和post方法:
export function get(url, params = {}, showError = true) {
const fly = createFly()
if (fly) {
return new Promise((resolve, reject) => {
fly.get(url, params).then(response => {
console.log(response)
if (response && response.data && response.data.error_code === 0) {
resolve(response)
} else {
if (showError) {
const msg = (response && response.data && response.data.msg) || '請求失敗'
mpvue.showToast({
title: msg,
duration: 2000
})
}
reject(response)
}
}).catch(err => {
handleError(err)
reject(err)
})
})
}
}
export function post(url, params = {}, showError = true) {
const fly = createFly()
if (fly) {
return new Promise((resolve, reject) => {
fly.post(url, params).then(response => {
console.log(response)
if (response && response.data && response.data.error_code === 0) {
resolve(response)
} else {
if (showError) {
const msg = (response && response.data && response.data.msg) || '請求失敗'
mpvue.showToast({
title: msg,
duration: 2000
})
}
reject(response)
}
}).catch(err => {
handleError(err)
reject(err)
})
})
}
}
五、圖書推薦組件“換一批”功能的實現
每一部分需要調用對應接口:
- https://test.youbaobao.xyz:18081/book/home/recommend/v2
- https://test.youbaobao.xyz:18081/book/home/freeRead/v2
- https://test.youbaobao.xyz:18081/book/home/hotBook/v2
每個接口都需要在src\api\index.js中暴露一個調用方法供頁面調用:
export function recommend() {
return get(`${API_URL}/book/home/recommend/v2`)
}
export function freeRead() {
return get(`${API_URL}/book/home/freeRead/v2`)
}
export function hotBook() {
return get(`${API_URL}/book/home/hotBook/v2`)
}
當然別忘了
import {getHomeData, recommend, freeRead, hotBook} from '../../api'
在src\pages\index\index.vue中創建調用接口的方法:
recommendChange(key) {
switch (key) {
case 'recommend':
// 這裏其實是直接調用接口中的數據,每次請求接口都會重新生成一組推薦數據
recommend().then(response => {
this.recommend = response.data.data
})
break
case 'freeRead':
freeRead().then(response => {
this.freeRead = response.data.data
})
break
case 'hotBook':
hotBook().then(response => {
this.hotBook = response.data.data
})
break
}
},
在src\pages\index\index.vue中調用新創建的方法
<HomeBook
title="爲你推薦"
:row="1"
:col="3"
:data="recommend"
mode="col"
btn-text="換一批"
@onMoreClick="recommendChange('recommend')"
@onBookClick="onHomeBookClick"/>
<HomeBook
title="免費閱讀"
:row="2"
:col="2"
:data="freeRead"
mode="row"
btn-text="換一批"
@onMoreClick="recommendChange('freeRead')"
@onBookClick="onHomeBookClick"/>
<HomeBook
title="當前最熱"
:row="1"
:col="4"
:data="hotBook"
mode="col"
btn-text="換一批"
@onMoreClick="recommendChange('hotBook')"
@onBookClick="onHomeBookClick"/>
<HomeBook
title="圖書分類"
:row="2"
:col="2"
:data="category"
mode="category"
btn-text="查看全部"
@onMoreClick="onCategoryMoreClick"
@onBookClick="onHomeBookClick"/>
爲了功能更加友好,需要在點擊換一批(圖片重新渲染)時顯示圖片的佔位符:完善src\components\base\ImageView.vue的監聽器:
watch: {
src(newValue, preValue) {
if (newValue && newValue.length > 0 && newValue !== preValue) {
this.$nextTick(() => {
this.isLoading = true
this.error = false
})
}
}
},
完成!