输入框热词滚动
网站搜索框中,滚动的热门商品效果
效果
属性
属性 | 描述 | 类型 | 默认值 | 可选值 |
---|---|---|---|---|
value/v-model | 输入框的值 | String | - | - |
list | 热词数组 每一项至少包含label,为输入框滚动显示的句子 |
Array | [] | - |
duration | 多长时间滚动一次 (ms) | Number | 3000 | - |
事件
事件名 | 描述 | 参数 |
---|---|---|
input | 输入框的值变化时触发 | (value: string) |
search | 点击搜索按钮或回车时触发 | (value: string) |
使用
<template>
<ScrollInput v-model="keyword" :list="serviceData" :duration="2500" />
</template>
<script>
import ScrollInput from '@/components/ScrollInput'
export default {
components: { ScrollInput },
data() {
return {
keyword: '',
serviceData: [
{ id: 1, label: '苹果15' },
{ id: 2, label: '洗衣机' },
{ id: 3, label: '笔记本' },
{ id: 4, label: '鼠标' },
]
}
},
}
</script>
代码
<!-- 输入框热词滚动组件 -->
<template>
<div class="input-wrapper">
<el-input
:value="value"
@input="handleInput"
@keyup.enter.native="search"
@compositionstart="handleStart"
clearable
style="width: 300px"
>
<el-button slot="append" @click="search" icon="el-icon-search"></el-button>
</el-input>
<ul class="hot-content" ref="scroll" v-show="showHotWords">
<li class="item" v-for="item in list" :key="item.id">
<!-- 火焰图标 -->
<svg
t="1686725353099"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2541"
width="20"
height="20"
>
<path
d="M423.477333 938.666667S45.045333 855.424 214.186667 442.282667c0 0 38.4 45.909333 33.12 68 0 0 30.101333-104.277333 95.072-166.570667C398.165333 290.186667 454.848 139.712 402.570667 85.333333c0 0 258.933333 54.378667 287.754666 326.378667 0 0 33.12-86.666667 101.12-95.232 0 0-20.906667 47.616 0 119.04 0 0 214.485333 367.146667-155.157333 491.242667 0 0 110.805333-125.813333-124.181333-341.717334 0 0-55.402667 115.626667-88.533334 156.373334-0.096 0.106667-92.522667 103.722667-0.096 197.248z"
fill="#ff000050"
p-id="2542"
></path>
</svg>
{{ item.label }}
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
// 输入框值
value: String,
// 数组对象,对象至少包含 label 属性
list: {
type: Array,
default: () => [],
},
// 多少毫秒滚动一次
duration: {
type: Number,
default: 3000,
},
},
data() {
return {
index: 0, // 当前热词的索引
timer: null, // 定时器,停止热词滚动
showHotWords: true, // 是否显示热词
inputHeight: 0, // 输入框高度,动态计算
}
},
mounted() {
this.inputHeight = this.$refs.scroll.clientHeight
this.$nextTick(this.move)
},
methods: {
/** 开始热词切换 */
move() {
this.timer = setInterval(() => {
this.index++
if (this.index === this.list.length) {
this.index = 0
}
this.$refs.scroll.style.transform = `translateY(-${this.inputHeight * this.index}px)`
}, this.duration)
},
/** 结束热词切换 */
stop() {
clearInterval(this.timer)
},
/** 用户开始输入 */
handleStart() {
// 为解决中文未提交时,输入框已有待提交的英文字母,但热词依旧显示
this.showHotWords = false // 可将此行注释,在输入框内输入中文,查看bug
},
handleInput(value) {
this.$emit('input', value)
this.showHotWords = value.length === 0
},
/** 处理搜索 */
search() {
const result = this.value || this.list[this.index].label
this.showHotWords = false
this.$emit('input', result)
this.$emit('search', result)
},
},
beforeDestroy() {
this.stop()
},
}
</script>
<style scoped lang="scss">
.input-wrapper {
position: relative;
overflow: hidden;
::v-deep .el-input-group__append {
background: #409eff;
border-color: #409eff;
color: #fff;
cursor: pointer;
}
.hot-content {
list-style: none;
height: 100%;
position: absolute;
top: 0;
left: 15px;
font-size: 14px;
color: rgba(0, 0, 0, 0.3);
user-select: none;
transition: 0.5s;
// 鼠标失效
pointer-events: none;
.item {
height: 100%;
display: flex;
align-items: center;
}
}
}
</style>