javascript
<template>
<view v-if="isPopupVisible" class="history-down-popup-mask" :style="maskStyle" @click="startHideAnimation">
<view class="history-down-popup-content" :class="{ 'history-slide-down': value && !isClosing, 'history-slide-up': isClosing }"
@click.stop>
<view class="history-history-keyword">
<view class="history-history-title space-between" @click="startHideAnimation">
<text>历史搜索</text>
<text class="qh-rt-single qh-rt-a-zu4416 close-popup-icon" style="font-size: 22rpx;" ></text>
</view>
<view class="history-history-tag-list">
<view v-for="(item, index) in historyList" :key="index" @tap="clickTaghandler(item)">{{ item }}
</view>
</view>
<view class="history-bottom" v-if="historyList.length > 0" >
<text @tap="clearHistory" class="feiIconfont icon-shanchu" ></text>
</view>
</view>
</view>
</view>
</template>
<script>
//本地的key
const HISTORY_KEY = 'history_list'
export default {
name: 'HistoryPopup',
props: {
value: {
type: Boolean,
default: false
},
topDistance: {
type: [Number, String],
default: 0
}
},
computed: {
maskStyle() {
return {
top: `${this.topDistance}rpx`,
height: `calc(100vh - ${this.topDistance}rpx)`
}
}
},
data() {
return {
historyList: [],
isPopupVisible: false,
isClosing: false
}
},
watch: {
value: {
immediate: true,
handler(newVal) {
if (newVal) {
this.isPopupVisible = true
this.isClosing = false
} else {
this.startHideAnimation()
}
}
}
},
created() {
this.loadHistory()
},
methods: {
startHideAnimation() {
if (!this.isPopupVisible) return
this.isClosing = true
setTimeout(() => {
this.isPopupVisible = false
this.isClosing = false
this.$emit('input', false)
}, 300)
},
loadHistory() {
try {
const history = uni.getStorageSync(HISTORY_KEY)
if (history) {
this.historyList = history
}
} catch (e) {
console.error('获取搜索历史失败:', e)
}
},
saveSearchHistory(keyword) {
if (!keyword.trim())return
try {
let history = this.historyList.filter(item => item !== keyword)
history.unshift(keyword)
history = history.slice(0, 10)
this.historyList = history
uni.setStorageSync(HISTORY_KEY, history)
} catch (e) {
console.error('保存搜索历史失败:', e)
}
},
clearHistory() {
try {
this.historyList = []
uni.removeStorageSync(HISTORY_KEY)
uni.showToast({
title: '已清空历史记录',
icon: 'none'
})
this.startHideAnimation()
// this.$parent.checkHistory()
} catch (e) {
console.error('清除搜索历史失败:', e)
uni.showToast({
title: '清除历史失败',
icon: 'none'
})
}
},
clickTaghandler(content) {
this.$emit('doSearch', {
value: content
})
}
}
}
</script>
<style lang="scss">
.history-bottom {
display: flex;
justify-content: flex-end;
text:last-child {
font-size: 22px;
}
}
.history-down-popup-mask {
position: fixed;
left: 0;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 99;
}
.history-down-popup-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: white;
z-index: 1000;
border-radius: 0 0 30rpx 30rpx;
transform: translateY(-100%);
}
.history-slide-down {
animation: slide-down 0.3s ease-out forwards;
}
.history-slide-up {
animation: slide-up 0.3s ease-in forwards;
}
@keyframes slide-down {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0);
}
}
@keyframes slide-up {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-100%);
}
}
.history-history-keyword {
padding: 30rpx;
.history-history-title {
font-size: 30rpx;
color: #222222;
display: flex;
justify-content: space-between;
align-items: center;
text:last-child {
color: #999;
}
}
.history-history-tag-list {
display: flex;
flex-wrap: wrap;
margin-top: 30rpx;
max-height: 300rpx;
overflow-y: auto;
view {
font-size: 25rpx;
color: #999;
border: 1rpx solid #999;
padding: 6rpx 15rpx;
margin: 15rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
border-radius: 12rpx;
}
}
}
</style>
父组件的调用