vue 2.0 实战移动音乐app(四)Scroll组件的抽象

scroll.vue

<template>
  <div ref="wrapper">
    <slot></slot>
  </div>
</template>

<script>
import BScroll from 'better-scroll'

export default {
  props: {
    probeType: {
      type: Number,
      default: 1
    },
    click: {
      type: Boolean,
      default: true
    },
    data: {
      type: Array,
      default: null
    }
  },
  mounted() {
    setTimeout(() => {
      this._initScroll()
    }, 20)
  },
  methods: {
    _initScroll() {
      if (!this.$refs.wrapper) {
        return
      }
      this.scroll = new BScroll(this.$refs.wrapper, {
        probeType: this.probeType,
        click: this.click
      })
      console.log(this.scroll)
    },
    enable() {
      this.scroll && this.scroll.enable()
    },
    disable() {
      this.scroll && this.scroll.disable()
    },
    refresh() {
      this.scroll && this.scroll.refresh()
    }
  },
  watch: {
    data() {
      setTimeout(() => {
        this._initScroll()
      }, 20)
    }
  }
}
</script>

recommend.vue

<template>
  <div class="recommend">
    <scroll class="recommend-content">
      <div>
        <div class="slider-wrapper" v-if="recommends.length">
          <slider>
            <div v-for="item in recommends" :key='item.id'>
              <a :href="item.linkUrl">
                <img :src="item.picUrl">
              </a>
            </div>
          </slider>
        </div>
        <div class="recommend-list">
          <h1 class="list-title">热门歌单推荐</h1>
          <ul>
            <li class="item" v-for="item in songList" :key="item.id">
              <div class="icon">
                <img :src="item.picUrl" width="60" height="60">
              </div>
              <div class="text">
                <p class="desc">{{item.songListDesc}}</p>
              </div>
            </li>
          </ul>
        </div>
        <div class="loading-container"></div>
      </div>
    </scroll>
  </div>
</template>

<script>
import Slider from 'base/slider/slider'
import Scroll from 'base/scroll/scroll'
import {getRecommend} from 'api/recommend'
import {ERR_OK} from 'api/config'

export default {
  data() {
    return {
      recommends: [],
      songList: []
    }
  },
  created() {
    this._getRecommend()
  },
  methods: {
    _getRecommend() {
      getRecommend().then((res) => {
        if (res.code === ERR_OK) {
          this.recommends = res.data.slider
          this.songList = res.data.songList
        }
      })
    }
  },
  components: {
    Slider, Scroll
  }
}
</script>

由于在我写的时候,轮播图数据和歌单数据是一起的,所以就同时获取了。(导致后面出现了问题

此时看到,wrapperHeight==scrollHeight=579.当然不能滚动。由于我们渲染滚动的时机是在mounted()的时候,数据渲染是一个动态的过程,所以需要时刻检测数据的变化。

给滚动绑定一个data

:data='songList'

此时确实可以滚动了,但是内层的高度却大得出奇。2738。导致错误。

这个错误我找了很久,后来我将歌单数据渲染的时间相较于轮播图往后延迟。就正常了。

_getRecommend() {
      getRecommend().then((res) => {
        if (res.code === ERR_OK) {
          this.recommends = res.data.slider
          setTimeout(() => {
            this.songList = res.data.songList
          })
        }
      })
    }

???表示不太理解。

这个问题解决了!!!

主要还是渲染时机不对,导致高度异常。要保证轮播图数据的获取,渲染完成后,才可以计算他的高度,否则计算的就是图片渲染前的实际高,肯定就偏高了。

这里有其他更好的解决的办法,除了上面使用到的,将歌单数据获取时间延迟,给轮播图充分的时间。然后再计算二者的高度。

第二种是使用nextTick(),表明只有当轮播图数据渲染完成才开始初始化滚动:

_getRecommend() {
      getRecommend().then((res) => {
        if (res.code === ERR_OK) {
          this.recommends = res.data.slider
          this.$nextTick(() => {
            this.songList = res.data.songList
          })
        }
      })
    }

第三种,既然高度总是计算不准,直接给一个固定高不就可以了嘛

给轮播图外层父组件固定高。

第四种,给图片的onload过程增加函数,刷新滚动。

总之轮播高度错误时通常和dom渲染时机有关。

猜你喜欢

转载自blog.csdn.net/weixin_42424660/article/details/84501979