文章目录
一、首页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
})
}
}
},
完成!