【筆記】實戰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
        })
      }
    }
  },

完成!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章