<template> <div class="search-input"> <i class="icon-search"></i> <input class="input-inner" v-model="query" :placeholder="placeholder" /> <i v-show="query" class="icon-dismiss" @click="clear" ></i> </div> </template> <script> import { debounce } from 'throttle-debounce' export default { name: 'search-input', props: { modelValue: String, placeholder: { type: String, default: '搜索歌曲、歌手' } }, data() { return { query: this.modelValue } }, created() { this.$watch('query', debounce(300, (newQuery) => { this.$emit('update:modelValue', newQuery.trim()) })) this.$watch('modelValue', (newVal) => { this.query = newVal }) }, methods: { clear() { this.query = '' } } } </script> <style lang="scss" scoped> .search-input { display: flex; align-items: center; box-sizing: border-box; width: 100%; padding: 0 6px; height: 32px; background: $color-highlight-background; border-radius: 6px; .icon-search { font-size: 24px; color: $color-text-d; } .input-inner { flex: 1; margin: 0 5px; line-height: 18px; background: $color-highlight-background; color: $color-text; font-size: $font-size-medium; outline: 0; &::placeholder { color: $color-text-d; } } .icon-dismiss { font-size: 16px; color: $color-text-d; } } </style>
<template> <div class="search-input"> <i class="icon-search"></i> <input class="input-inner" v-model="query" :placeholder="placeholder" /> <i v-show="query" class="icon-dismiss" @click="clear" ></i> </div> </template> <script> import { debounce } from 'throttle-debounce' export default { name: 'search-input', props: { modelValue: String, placeholder: { type: String, default: '搜索歌曲、歌手' } }, data() { return { query: this.modelValue } }, created() { this.$watch('query', debounce(300, (newQuery) => { this.$emit('update:modelValue', newQuery.trim()) })) this.$watch('modelValue', (newVal) => { this.query = newVal }) }, methods: { clear() { this.query = '' } } } </script> <style lang="scss" scoped> .search-input { display: flex; align-items: center; box-sizing: border-box; width: 100%; padding: 0 6px; height: 32px; background: $color-highlight-background; border-radius: 6px; .icon-search { font-size: 24px; color: $color-text-d; } .input-inner { flex: 1; margin: 0 5px; line-height: 18px; background: $color-highlight-background; color: $color-text; font-size: $font-size-medium; outline: 0; &::placeholder { color: $color-text-d; } } .icon-dismiss { font-size: 16px; color: $color-text-d; } } </style>
主要用的是 debounce 这个库, 类似于 定时器的定时功能
debounce 实现
由于 debounce
n 只是往后推延函数的执行时间,并不具有 throttle
每隔一段时间一定会执行的能力,所以其实现起来更加简单:
function debounce(delay, callback) { let timeoutID; function wrapper() { const self = this; const args = arguments; function exec() { callback.apply(self, args); } clearTimeout(timeoutID); timeoutID = setTimeout(exec, delay); } return wrapper; }