首页开发 | 「小慕读书」官网
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)
}
import {getHomeData} from '../../api'
export default {
...
methods: {
getHomeData() {
getHomeData({openId: '1234'}).then(response => {
console.log(response)
})
},
...
试用:
export default {
...
mounted() {
console.log(this.getHomeData())
},
...
data() {
return {
hotSearch: '',
shelf: [],
banner: {},
recommend: [],
freeRead: [],
hotBook: [],
category: []
}
},
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)
})
})
}
}
这样就更符合我们所要请求的数据格式
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
})
},
...
<HomeCard :data="homeCard"/>
<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"/>
修改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)
})
})
}
}
每一部分需要调用对应接口:
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
})
}
}
},
完成!