searc页面有一个搜索框search-box
<template>
<div class="search-box">
<i class="icon-search"></i>
<input type="text" class="box" v-model="query" :placeholder="placeHolder" ref="inputQuery">
<i v-show="query" class="icon-dismiss" @click="clear"></i>
</div>
</template>
v-model属性可以将数据双向绑定
export default {
props: {
placeHolder: { // 接受父组件的传递
type: String,
default: '搜索歌曲、歌手'
}
},
data () {
return {
query: ''
}
},
methods: {
clear () { // 清除搜索内容
this.query = ''
},
setQuery (query) { // 提供接口
this.query = query
},
blur () {
this.$refs.inputQuery.blur() // 提供接口 清除光标
}
},
created () {
this.$watch('query', deBounce((newQuery) => { // 节流函数 使$emit事件在200ms后发送,
this.$emit('query', newQuery)
}, 200))
}
}
。。。
节流函数
export function deBounce (func, delay) {
let timer
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => { // 如果外部的函数反复被执行。delay了内部的func的函数,达到函数截留的作用
func.apply(this, args)
}, delay)
}
}
search组件
<template>
<div class="search">
<div class="search-box-wrapper">
<search-box ref="searchBox" @query="onQueryChange"></search-box>
</div>
<div class="shortcut-wrapper" ref="shortcutWrapper" v-show="!query">
<Scroll class="shortcut" :refreshDelay="refreshDelay" ref="shortcut" :data="shortcut">
<div>
<div class="hot-key">
<h1 class="title">热门搜索</h1>
<ul>
<li v-for="item in hotKey" :key="item.id" class="item" @click="addQuery(item.k)">
<span>{{item.k}}</span>
</li>
</ul>
</div>
<div class="search-history" v-show="searchHistory.length">
<h1 class="title">
<span class="text">搜索历史</span>
<span class="clear" @click="showConfirm">
<i class="icon-clear"></i>
</span>
</h1>
<SearchList @select="addQuery" :searches="searchHistory" @deleteOne="deleteOne"></SearchList>
</div>
</div>
</Scroll>
</div>
<div class="search-result" v-show="query" ref="searchResult">
<suggest :query="query" @listScroll="blurInput" @select="saveSearch" ref="suggest"></suggest>
</div>
<confrim ref="confirm" :text="text" confirmBtnText="清空" @confirm="deleteAll" @cancel="cancel"></confrim>
<router-view></router-view>
</div>
</template>
<script>
import SearchBox from '../../base/search-box/search-box'
import {getSearchHot} from '../../Api/search'
import {ERR_OK} from '../../Api/config'
import Suggest from 'components/suggest/suggest'
import {mapActions, mapGetters} from 'vuex'
import SearchList from '../../base/search-list/search-list'
import Confrim from '../../base/confirm/confirm'
import Scroll from '../../base/scroll/scroll'
import {playlistMixin, searchMixin} from 'common/js/mixin'
export default {
mixins: [playlistMixin, searchMixin],
created () {
this._getSearchHot()
},
data () {
return {
hotKey: [],
query: '',
text: '确定要清除所有历史记录?',
refreshDelay: 100
}
},
computed: {
shortcut () {
return this.hotKey.concat(this.searchHistory)
},
...mapGetters([
'searchHistory'
])
},
watch: {
query (newQuery) {
if (!newQuery) { // 若query不再发生变化,则手动刷新scroll
setTimeout(() => {
this.$refs.shortcut.refresh()
}, 20)
}
}
},
methods: {
handlePlayList (playlist) {
const bottom = playlist.length > 0 ? '60px' : ''
this.$refs.shortcutWrapper.style.bottom = bottom
this.$refs.shortcut.refresh()
this.$refs.searchResult.style.bottom = bottom
this.$refs.suggest.refresh()
},
addQuery (query) { // 点击标签,将数据传到search-box中在搜索栏显示
this.$refs.searchBox.setQuery(query) // 调用子组件方法/接口
},
onQueryChange (newQuery) { // 将search-box中改变的query发送出来,使父组件同步改变
this.query = newQuery
},
blurInput () { // 去掉键盘 => 即使input失去焦点
this.$refs.searchBox.blur() // 调用子组件方法
},
saveSearch () {
this.saveSearchHistory(this.query)
},
deleteOne (item) {
this.deleteSearchHistory(item)
},
showConfirm () {
this.$refs.confirm.show()
},
deleteAll () {
this.clearSearchHistory()
this.$refs.confirm.hide()
},
cancel () {
this.$refs.confirm.hide()
},
_getSearchHot () {
getSearchHot().then((res) => {
if (res.code === ERR_OK) {
this.hotKey = res.data.hotkey.slice(0, 10) // 截取前十个数据
}
})
},
...mapActions([
'saveSearchHistory',
'deleteSearchHistory',
'clearSearchHistory'
])
},
components: {
SearchBox,
Suggest,
SearchList,
Confrim,
Scroll
}
}
</script>
scroll实现下拉刷新
主要在于下拉是后触发一个事件,而此事件决定再发送一次请求,获得更多数据
这位兄弟总结的很好
https://blog.csdn.net/weixin_40814356/article/details/80478440