223 lines
5.3 KiB
Vue
223 lines
5.3 KiB
Vue
<template>
|
||
<view v-if="visible" class="brand-selector-overlay" @click="handleClose">
|
||
<view class="brand-selector-container" @click.stop>
|
||
<!-- 头部 -->
|
||
<view class="selector-header">
|
||
<view class="header-left" @click="handleClose">
|
||
<text class="close-icon">×</text>
|
||
</view>
|
||
<view class="header-title">选择品牌</view>
|
||
<view class="header-right" @click="handleConfirm">
|
||
<text class="confirm-btn">完成</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 搜索框(增加层级隔离+样式重置) -->
|
||
<view class="search-bar">
|
||
<view class="search-input">
|
||
<uni-icons class="search-icon" type="search" size="20" color="#CCCCCC"></uni-icons>
|
||
<input
|
||
type="text"
|
||
placeholder="搜索品牌名称"
|
||
placeholder-class="input-placeholder"
|
||
v-model="searchKeyword"
|
||
class="input"
|
||
@input="handleSearchInput"
|
||
/>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 品牌列表 -->
|
||
<view class="brand-list">
|
||
<view
|
||
class="brand-item"
|
||
:class="{active: selectedBrand === item.name}"
|
||
v-for="item in filteredBrandList"
|
||
:key="item.name"
|
||
@click="selectBrand(item.name)"
|
||
>
|
||
{{ item.name }}
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 品牌管理入口 -->
|
||
<view class="brand-management" @click="handleToBrandManagement">
|
||
<text class="management-text">品牌管理</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'BrandSelector',
|
||
props: {
|
||
visible: { type: Boolean, default: false },
|
||
defaultValue: { type: String, default: '默认品牌' },
|
||
brandList: { type: Array, default: () => [{ name: '默认品牌' }] }
|
||
},
|
||
data() {
|
||
return {
|
||
selectedBrand: this.defaultValue,
|
||
searchKeyword: ''
|
||
}
|
||
},
|
||
watch: {
|
||
defaultValue(newVal) {
|
||
this.selectedBrand = newVal
|
||
}
|
||
},
|
||
computed: {
|
||
filteredBrandList() {
|
||
if (!this.searchKeyword) return this.brandList
|
||
return this.brandList.filter(item =>
|
||
item.name.toLowerCase().includes(this.searchKeyword.toLowerCase())
|
||
)
|
||
}
|
||
},
|
||
methods: {
|
||
selectBrand(brandName) {
|
||
this.selectedBrand = brandName
|
||
},
|
||
handleConfirm() {
|
||
this.$emit('confirm', this.selectedBrand)
|
||
this.handleClose()
|
||
},
|
||
handleClose() {
|
||
this.$emit('close')
|
||
},
|
||
handleToBrandManagement() {
|
||
this.$emit('toBrandManagement')
|
||
},
|
||
handleSearchInput(e) {
|
||
this.searchKeyword = e.detail.value
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
// 基础遮罩层
|
||
.brand-selector-overlay {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
display: flex;
|
||
align-items: flex-end;
|
||
z-index: 999;
|
||
}
|
||
|
||
// 容器
|
||
.brand-selector-container {
|
||
width: 100%;
|
||
background: #FFFFFF;
|
||
border-radius: 16rpx 16rpx 0 0;
|
||
max-height: 80vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
z-index: 1000;
|
||
}
|
||
|
||
// 头部
|
||
.selector-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 24rpx 32rpx;
|
||
border-bottom: 1rpx solid #F5F5F5;
|
||
|
||
.close-icon { font-size: 36rpx; color: #666666; font-weight: 400; }
|
||
.header-title { font-size: 32rpx; font-weight: 500; color: #333333; }
|
||
.confirm-btn { font-size: 30rpx; color: #E62429; font-weight: 400; }
|
||
}
|
||
|
||
// 搜索框:终极修复版(解决覆盖+还原视觉)
|
||
.search-bar {
|
||
padding: 20rpx 32rpx;
|
||
background: #FFFFFF;
|
||
position: relative;
|
||
z-index: 1001; // 确保搜索框在最上层
|
||
|
||
.search-input {
|
||
display: flex;
|
||
align-items: center;
|
||
background: #FFFFFF !important;
|
||
border: 1rpx solid #E8E8E8;
|
||
border-radius: 8rpx;
|
||
height: 76rpx;
|
||
padding: 0 24rpx;
|
||
position: relative;
|
||
z-index: 1002; // 确保输入框容器层级最高
|
||
|
||
.search-icon {
|
||
margin-right: 16rpx;
|
||
color: #CCCCCC !important;
|
||
flex-shrink: 0;
|
||
position: relative;
|
||
z-index: 1; // 图标层级低于输入框文字
|
||
}
|
||
|
||
.input {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
color: #333333 !important; // 强制文字颜色,防止被全局样式覆盖
|
||
border: none !important;
|
||
outline: none !important;
|
||
background: transparent !important;
|
||
padding: 0; // 彻底移除内边距,避免行高冲突
|
||
line-height: 76rpx; // 行高与容器高度一致,确保垂直居中
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
position: relative;
|
||
z-index: 2; // 确保文字在最上层,不被任何元素遮挡
|
||
}
|
||
|
||
.input-placeholder {
|
||
font-size: 28rpx;
|
||
color: #CCCCCC !important;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 品牌列表
|
||
.brand-list {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
|
||
.brand-item {
|
||
padding: 28rpx 32rpx;
|
||
border-bottom: 1rpx solid #F5F5F5;
|
||
font-size: 30rpx;
|
||
color: #333333;
|
||
position: relative;
|
||
font-weight: 400;
|
||
|
||
&.active {
|
||
color: #E62429;
|
||
&::after {
|
||
content: "✓";
|
||
position: absolute;
|
||
right: 32rpx;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 品牌管理入口
|
||
.brand-management {
|
||
padding: 28rpx 32rpx;
|
||
text-align: center;
|
||
color: #1677FF;
|
||
font-size: 28rpx;
|
||
border-top: 1rpx solid #F5F5F5;
|
||
font-weight: 400;
|
||
}
|
||
</style> |