Files
tra-app/src/pages/search/search.vue
T

347 lines
8.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="main_div max_page">
<nav-bar :is_seat="false"></nav-bar>
<view class="fixed_search_div">
<view class="back_div" @click="common.navigateBack()">
<view class="back-icon"></view>
</view>
<view class="fixed_search_input_div fl1">
<uv-input v-model="inputValue" shape="circle" :customStyle="fixedCustomStyles"
placeholderStyle='color:#999999;font-size:26rpx' placeholder="请输入关键字" suffixIcon="search"
:suffixIconStyle="suffixIconStyle" :focus="true">
</uv-input>
</view>
<view class="message_div" v-show="false">
<image src="@/static/images/index/message_b.png" class="message_img"></image>
<view class="message_text">消息</view>
<view class="message_num">30</view>
</view>
</view>
<!-- 主体 -->
<view class="search_content">
<!-- 历史搜索 -->
<view class="title_div">
<view class="text">
历史搜索
</view>
<view class="fl1">
</view>
<view class="delete_img">
<image src="@/static/images/search/delete.png" class="img" mode="heightFix"></image>
</view>
</view>
<view class="history_div">
<view class="history_item" v-for="item in historyList">
{{item}}
</view>
<view class="history_item has-arrow" @click="show_all_history_fun">
<view class="down-corner-arrow" :class="show_all_history ? 'up' : 'down'"></view>
</view>
</view>
</view>
<view class="host_search_div">
</view>
<image class="bg_img" style="width: 718rpx;height: 1126rpx;" src="@/static/images/test/search_img.png">
</image>
<!-- 隐藏的计算容器 -->
<view class="measure-container">
<view v-for="(item, index) in hiddenHistorySearchList" :key="index" class="history_item">
{{ item }}
</view>
</view>
</view>
</template>
<script setup>
const tagRefs = ref([]) // 用于存储所有history_item的引用
import {
getCurrentInstance,
computed,
watch
} from 'vue';
const {
proxy
} = getCurrentInstance() // 获取当前组件实例
const currentHeight = ref(0); // 动态高度(单位:px
const visibleCount = ref(0)
const hiddenHistorySearchList = ref([]);
// 展开或者关闭
const show_all_history_fun = async () => {
show_all_history.value = !show_all_history.value
}
const show_all_history = ref(false)
const historyList = computed(() => show_all_history.value ? hiddenHistorySearchList.value : hiddenHistorySearchList
.value.slice(0, visibleCount.value));
onShow(() => {
const historySearchList = ['房贷审批', '小微贷条件', '对公开户', '反洗钱指引', '盗刷处理', '小微贷条件', '征信解读']
if (historySearchList) {
hiddenHistorySearchList.value = [...historySearchList]
nextTick(() => {
const widthPromises = hiddenHistorySearchList.value.map((res, index) => {
return new Promise(resolve => {
const query = uni.createSelectorQuery().in(proxy);
query.select(`.history_item:nth-child(${index + 1})`)
.boundingClientRect(data => {
resolve(data ? data.width : 0); // 解析宽度值
}).exec();
});
});
// 等待所有Promise完成
Promise.all(widthPromises).then(widths => {
console.log('所有宽度计算完成:', widths);
calculateLayout(widths); // 开始计算布局
});
})
}
})
const calculateLayout = (widths) => {
const gap = 12; // 项之间的间距
const expandBtnWidth = 80
const query = uni.createSelectorQuery().in(proxy);
query.select('.history_div')
.boundingClientRect(data => {
const containerWidth = data.width
let row1Count = 0; // 第一行可容纳数量
let row2Count = 0; // 第二行可容纳数量
let currentWidth = 0; // 当前行已用宽度
// 计算第一行可容纳数量
for (let i = 0; i < widths.length; i++) {
const itemWidth = widths[i] + (row1Count > 0 ? gap : 0);
if (currentWidth + itemWidth <= containerWidth) {
row1Count++;
currentWidth += itemWidth;
} else {
break;
}
}
// 计算第二行可容纳数量(预留展开按钮位置)
currentWidth = 0;
// 第二行总可用宽度 = 容器宽度 - 展开按钮宽度(含间距)
const row2MaxWidth = containerWidth - expandBtnWidth - gap;
for (let i = row1Count; i < widths.length; i++) {
const itemWidth = widths[i] + (row2Count > 0 ? gap : 0);
if (currentWidth + itemWidth <= row2MaxWidth) {
row2Count++;
currentWidth += itemWidth;
} else {
break;
}
}
console.log(`第一行: ${row1Count}个,第二行: ${row2Count}个(含展开按钮)`);
visibleCount.value = row1Count + row2Count;
}).exec();
}
import {
ref,
watchEffect,
nextTick,
onMounted
} from 'vue';
import common from '@/common/common.js'
import {
onShow
} from '@dcloudio/uni-app';
// 静态样式配置
const fixedCustomStyles = {
backgroundColor: "#ffffff",
paddingLeft: "40rpx",
paddingTop: "5px",
paddingBottom: "5px",
border: "none"
}
const suffixIconStyle = {
color: "#2c8ef2",
fontSize: "28px"
}
const inputValue = ref('');
const measureRef = ref(null)
const measureItems = ref([])
</script>
<style scoped lang="scss">
.history_div {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.measure-container {
display: flex;
position: fixed;
top:-500rpx; // 藏起来,让他看不到
}
.history_item {
white-space: nowrap;
padding: 8rpx 22rpx;
border-radius: 40rpx 40rpx 40rpx 40rpx;
border: 1px solid #999;
color: #777;
}
.history_item {
margin-bottom: 16rpx;
}
/* 除最后一个子元素外,都添加右间距 */
.history_item:not(:last-child) {
margin-right: 12px;
}
.has-arrow {
border: 1px solid #bbb;
position: relative;
}
/* 朝下的拐角箭头容器 */
.down-corner-arrow {
padding: 10rpx 8rpx;
position: relative;
}
.down-corner-arrow.up {
transform: rotate(90deg);
top: 0%;
left: 0%;
}
.down-corner-arrow.down {
transform: rotate(-90deg);
top: 50%;
left: 0%;
}
/* 左半边箭头(向左旋转) */
.down-corner-arrow::before {
content: '';
position: absolute;
width: 20rpx;
/* 线段长度 */
height: 2rpx;
/* 线段粗细 */
background-color: #bbb;
transform-origin: right center;
/* 旋转中心在右侧 */
transform: rotate(-48deg);
/* 向左旋转50°,使总开口角100° */
}
/* 右半边箭头(向右旋转) */
.down-corner-arrow::after {
content: '';
position: absolute;
width: 20rpx;
/* 线段长度 */
height: 2rpx;
/* 线段粗细 */
background-color: #bbb;
transform-origin: right center;
/* 旋转中心在右侧 */
transform: rotate(48deg);
/* 向右旋转50°,使总开口角100° */
}
.title_div {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 70rpx;
margin: 10rpx 0;
// background-color: red;
.text {
font-size: 32rpx;
font-weight: bold;
}
.delete_img {
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx 0 20rpx 32rpx;
// background-color: red;
.img {
height: 24rpx;
}
}
}
.search_content {
background-color: #fff;
margin-top: -6rpx;
border-radius: 12rpx 12rpx 0 0;
display: flex;
flex-direction: column;
align-items: center;
padding: 0 20rpx;
min-height: 200rpx;
transition: max-height 0.3s ease;
.bg_img {
width: 84%;
margin: 20rpx auto;
}
}
.fixed_search_div {
padding: calc(10rpx + var(--status-bar-height)) 15rpx 24rpx 10rpx;
background: linear-gradient(90deg, #F1F7FF 0%, #D8EDFF 50%, #C3E6FF 100%);
display: flex;
align-items: center;
.back_div {
// margin-right: 10rpx;
padding: 10rpx 10rpx 10rpx 20rpx;
// background-color: red;
.back-icon {
position: relative;
width: 40rpx;
height: 40rpx;
cursor: pointer;
}
.back-icon::before,
.back-icon::after {
content: '';
position: absolute;
transition: all 0.3s ease;
}
.back-icon::after {
top: 25%;
left: 25%;
width: 40%;
height: 40%;
border-top: 4rpx solid #2B2C2E;
border-left: 4rpx solid #2B2C2E;
transform: rotate(-45deg);
}
}
}
.main_div {
display: flex;
flex-direction: column;
}
</style>