347 lines
8.1 KiB
Vue
347 lines
8.1 KiB
Vue
<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> |