vur-music(16)search组件

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值