ry_app/pages/BrandSelector/BrandSelector.vue

184 lines
3.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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-box">
<input
class="search-input"
type="text"
placeholder="搜索品牌名称"
v-model="searchKeyword"
/>
</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.includes(this.searchKeyword)
)
}
},
methods: {
selectBrand(brandName) {
this.selectedBrand = brandName
},
handleConfirm() {
this.$emit('confirm', this.selectedBrand)
this.handleClose()
},
handleClose() {
this.$emit('close')
},
handleToBrandManagement() {
this.$emit('toBrandManagement')
}
}
}
</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: #fff;
border-radius: 16rpx 16rpx 0 0;
max-height: 80vh;
display: flex;
flex-direction: column;
}
.selector-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
.close-icon {
font-size: 36rpx;
color: #666;
}
.header-title {
font-size: 32rpx;
font-weight: 500;
color: #333;
}
.confirm-btn {
font-size: 30rpx;
color: #E62429;
}
}
.search-box {
padding: 20rpx 30rpx;
.search-input {
width: 100%;
padding: 20rpx;
background: #f5f5f5;
border-radius: 8rpx;
font-size: 28rpx;
}
}
.brand-list {
flex: 1;
overflow-y: auto;
.brand-item {
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
font-size: 30rpx;
color: #333;
position: relative;
&.active {
color: #E62429;
&::after {
content: "✓";
position: absolute;
right: 30rpx;
top: 50%;
transform: translateY(-50%);
font-size: 28rpx;
}
}
}
}
.brand-management {
padding: 30rpx;
text-align: center;
color: #1677FF;
font-size: 28rpx;
border-top: 1rpx solid #f0f0f0;
}
</style>