1. 经典搜索框search-box.vue
通用组件的设计原则:解耦
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. 搜索框下拉加载更多
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
标记页码
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组件
4. 滚动
滚动scroll.vue组件包含两部分数据:hotKey searchHistory,两部分数据需要通过计算属性computed组合concat起来,然后传入scroll.vue组件:data中
5.优化
1. query变化
当query从有到无的时候,下面的dom结构display发生了改变,一次需要scroll刷新
在watch中,刷新scroll
watch: { query(newQuery) { if (!newQuery) { setTimeout(() => { this.$refs.scroll.refresh() }, 20) } }},