【笔记】实战mpvue2.0多端小程序框架——首页开发(下)


首页开发 | 「小慕读书」官网


一、首页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
        })
      }
    }
  },

完成!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序边界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值