1

1. 经典搜索框search-box.vue

clipboard.png
通用组件的设计原则:解耦

1. 通过props,传递placeholder信息

  props: {
    placeholder: {
      type: String,
      default: '搜索歌曲、歌手'
    }
  },

2. 派发输入框中的输入值query

 created() {
    //优化:添加节流函数
    this.$watch('query', _debounce((newQuery) => {
      this.$emit('query', newQuery)
    }, 300))
  },

3. 移动端收起键盘

开始滚动的时候在移动端输入框的键盘收缩,由父组件search.vue中开始滚动派发的事件,调用该方法,参考图片

blur() {
  this.$refs.query.blur()
}

2. 搜索框下拉加载更多

clipboard.png

1. 滚动至底部派发事件

首先滚动至底部派发事件在scroll.vue组件中
这里是通过props,如果需要传值,则派发滚动至底部事件
伪代码:

//滚动开始派发事件
    beforeScroll: {
      type: Boolean,
      default: false
    }
    
    ....
 _initScroll() {
  this.scroll = new BScroll(this.$refs.wrapper, {
    probeType: this.probeType,
    click: this.click
  })

  //上拉刷新,滚动到底部派发一个事件
  if (this.pullup) {
    this.scroll.on('scrollEnd', () => {
      if (this.scroll.y <= (this.scroll.maxScrollY + 50)) {
        this.$emit('scrollToEnd')
      }
    })
  }
}

2.接收派发事件

在suggest.vue中接收派发事件

  • hasMore标志位进行判断,是否可以加载更多
  • page标记页码

clipboard.png

searchMore() {
  //当没有的时候停止加载
  if (!this.hasMore) {
    return
  }
  //页码page更改
  this.page++

  search(this.query, this.page, this.showSinger, perpage).then((res) => {
    if (res.code === ERR_OK) {
      //concat拼接
      this.result = this.result.concat(this._genResult(res.data))
      this._checkMore(res.data)
    }
  })
},
/**
     * 上拉刷新,是否还有数据
     */
_checkMore(data) {
  const song = data.song
  //如果没有song或者  加载的数量 >
  if (!song.list.length || (song.curnum + song.curpage * perpage) >= song.totalnum) {
    this.hasMore = false
  }
},
search() {
  //下次搜索的时候初始化
  this.page = 1
  this.$refs.suggest.scrollTo(0, 0)
  this.hasMore = true

  //search是请求接口数据方法
  search(this.query, this.page, this.showSinger, perpage).then((res) => {
    if (res.code === ERR_OK) {
      this.result = this._genResult(res.data)
      this._checkMore(res.data)
    }
  })
},

3. 搜索状态优化

  • 加载状态:loading组件
  • 搜索结果: no-result组件

clipboard.png

4. 滚动

滚动scroll.vue组件包含两部分数据:hotKey searchHistory,两部分数据需要通过计算属性computed组合concat起来,然后传入scroll.vue组件:data中
clipboard.png

5.优化

1. query变化

当query从有到无的时候,下面的dom结构display发生了改变,一次需要scroll刷新

<div ref="shortCutWrapper" class="shortcut-wrapper" v-show="!query">
   <scroll ref="scroll" class="shortcut" :data="shortcut">
</div>

在watch中,刷新scroll

watch: {
    query(newQuery) {
      if (!newQuery) {
        setTimeout(() => {
          this.$refs.scroll.refresh()
        }, 20)
      }
    }
},

云深不知处
431 声望10 粉丝