完成consumer端同步
This commit is contained in:
88
components/consumer/SearchBar.uvue
Normal file
88
components/consumer/SearchBar.uvue
Normal file
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<view class="search-bar" v-if="mode==='readonly'" :style="{ paddingRight: internalCapsuleRight + 'px' }">
|
||||
<view class="search-box" @click="onClick">
|
||||
<image class="icon" src="/static/icons/search.png" />
|
||||
<text class="placeholder">{{ placeholder }}</text>
|
||||
</view>
|
||||
<view class="right-slot">
|
||||
<slot name="right"></slot>
|
||||
<view v-if="showActionButton" class="action-btn" @click.stop="onActionClick">搜索</view>
|
||||
<image v-if="showCamera" class="camera-icon" src="/static/icons/camera.png" @click.stop="$emit('camera')" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="search-bar" v-else :style="{ paddingRight: internalCapsuleRight + 'px' }">
|
||||
<view class="search-box">
|
||||
<image class="icon" src="/static/icons/search.png" />
|
||||
<input class="search-input" :placeholder="placeholder" v-model="internalValue" @input="onInput" @confirm="onConfirm" />
|
||||
</view>
|
||||
<view class="right-slot">
|
||||
<slot name="right"></slot>
|
||||
<view v-if="showActionButton" class="action-btn" @click.stop="onActionClick">搜索</view>
|
||||
<image v-if="showCamera" class="camera-icon" src="/static/icons/camera.png" @click.stop="$emit('camera')" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
import { getNavMetrics } from '@/utils/navUtils.uts'
|
||||
export default {
|
||||
props: {
|
||||
placeholder: { type: String, default: '搜索商品、店铺…' },
|
||||
mode: { type: String, default: 'readonly' }, // 'readonly' | 'input'
|
||||
autoNavigate: { type: Boolean, default: true },
|
||||
capsuleRight: { type: [Number, String], default: 0 },
|
||||
showActionButton: { type: Boolean, default: true },
|
||||
showCamera: { type: Boolean, default: false },
|
||||
value: { type: String, default: '' }
|
||||
},
|
||||
created() {
|
||||
// 计算默认的胶囊右侧预留
|
||||
try {
|
||||
const metrics = getNavMetrics()
|
||||
// 如果传入 props capsuleRight 为 0 或空,则使用自动计算值
|
||||
this.internalCapsuleRight = (this.capsuleRight && Number(this.capsuleRight) > 0) ? Number(this.capsuleRight) : (metrics.navRightReserve || 0)
|
||||
} catch (e) {
|
||||
this.internalCapsuleRight = (this.capsuleRight && Number(this.capsuleRight) > 0) ? Number(this.capsuleRight) : 0
|
||||
}
|
||||
},
|
||||
data() { return { internalValue: this.value, internalCapsuleRight: 0 } },
|
||||
watch: {
|
||||
value(newVal) { this.internalValue = newVal }
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('click')
|
||||
if (this.mode === 'readonly' && this.autoNavigate) {
|
||||
try { uni.navigateTo({ url: '/pages/mall/consumer/search' }) } catch (e) {}
|
||||
}
|
||||
},
|
||||
onActionClick() {
|
||||
// 优先触发 action 事件,包含当前输入或占位词
|
||||
const payload = (this.internalValue && this.internalValue.length > 0) ? this.internalValue : this.placeholder
|
||||
this.$emit('action', payload)
|
||||
},
|
||||
onInput(e) {
|
||||
const val = e && e.detail ? e.detail.value : (e || '')
|
||||
this.internalValue = val
|
||||
this.$emit('update:value', val)
|
||||
this.$emit('input', val)
|
||||
},
|
||||
onConfirm(e) {
|
||||
const confirmed = e && e.detail ? e.detail.value : this.internalValue
|
||||
this.$emit('confirm', confirmed)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.search-bar { display:flex; align-items:center; padding:12rpx 16rpx; background:transparent }
|
||||
.search-box { flex:1; display:flex; align-items:center; background:#ffffff; border-radius:999rpx; padding:10rpx 12rpx; box-shadow:0 2rpx 8rpx rgba(0,0,0,0.04); height:44rpx; border:1rpx solid rgba(0,0,0,0.05) }
|
||||
.icon { width:36rpx; height:36rpx; margin-right:12rpx }
|
||||
.placeholder { color:#b8b8b8; font-size:26rpx; padding-right:6rpx }
|
||||
.search-input { flex:1; height:40rpx; font-size:26rpx; color:#222; padding:0 }
|
||||
.right-slot { margin-left:12rpx; display:flex; align-items:center }
|
||||
.action-btn { background:#ff5000; color:#fff; padding:10rpx 20rpx; border-radius:16rpx; font-size:26rpx; font-weight:500 }
|
||||
.camera-icon { width:28rpx; height:28rpx; margin-left:8rpx }
|
||||
</style>
|
||||
Reference in New Issue
Block a user