134 lines
3.2 KiB
Vue
134 lines
3.2 KiB
Vue
<template>
|
||
<!-- 搜索栏 -->
|
||
<view class="search-bar" id="searchBar">
|
||
<!-- 状态栏占位盒子:避开系统导航栏,不影响下方 CSS padding -->
|
||
<view class="status-bar-placeholder" :style="{ height: statusBarHeight + 'px' }"></view>
|
||
<view class="search-input-wrap">
|
||
<image class="search-icon" src="/static/icons/products/icon_search.png" mode="aspectFit" />
|
||
<input
|
||
class="search-input"
|
||
placeholder="搜索产品"
|
||
placeholder-class="search-placeholder"
|
||
:value="keyword"
|
||
@input="onInput"
|
||
@blur="onBlur"
|
||
@confirm="onConfirm"
|
||
/>
|
||
<view class="search-btn" @tap="onSearch">搜索</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'SearchBar',
|
||
props: {
|
||
keyword: {
|
||
type: String,
|
||
default: ''
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
statusBarHeight: 20
|
||
}
|
||
},
|
||
created() {
|
||
try {
|
||
var sysInfo = uni.getSystemInfoSync()
|
||
var h = sysInfo.statusBarHeight
|
||
// 获取失败/异常值时用 20px 保底
|
||
this.statusBarHeight = typeof h === 'number' && h > 0 ? h : 20
|
||
} catch (e) {
|
||
this.statusBarHeight = 20
|
||
}
|
||
},
|
||
mounted() {
|
||
// 测量自身高度并 emit 给父组件(小程序端无法跨组件查询 DOM,必须自测量)
|
||
this.$nextTick(() => this.emitHeight())
|
||
},
|
||
methods: {
|
||
emitHeight() {
|
||
const query = uni.createSelectorQuery().in(this)
|
||
query.select('#searchBar').boundingClientRect()
|
||
query.exec((res) => {
|
||
if (res && res[0]) {
|
||
this.$emit('height-change', res[0].height)
|
||
}
|
||
})
|
||
},
|
||
onInput(e) {
|
||
this.$emit('input', e.detail.value)
|
||
},
|
||
onBlur() {
|
||
this.$emit('blur')
|
||
},
|
||
onConfirm() {
|
||
// 键盘确认键与搜索按钮同一行为
|
||
this.$emit('blur')
|
||
},
|
||
onSearch() {
|
||
this.$emit('search')
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 设计稿:左右留白 10px(20rpx),下留白 6px(12rpx),搜索框 209x32px(402x62rpx);上边距 56rpx 让搜索栏整体下移 */
|
||
.search-bar {
|
||
padding: 10rpx 20rpx 12rpx;
|
||
background: #ffffff;
|
||
box-sizing: border-box;
|
||
}
|
||
/* 状态栏占位:高度由 JS 内联指定(statusBarHeight) */
|
||
.status-bar-placeholder {
|
||
width: 100%;
|
||
}
|
||
.search-input-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 62rpx;
|
||
padding: 0 4rpx 0 21rpx;
|
||
background: #f5f5f5;
|
||
border-radius: 31rpx;
|
||
box-sizing: border-box;
|
||
/* 小程序端:只占左侧大部分宽度(设计稿 402rpx) */
|
||
/* #ifdef MP */
|
||
width: 402rpx;
|
||
/* #endif */
|
||
/* 非小程序(H5/App):占整行 */
|
||
/* #ifndef MP */
|
||
width: 100%;
|
||
/* #endif */
|
||
}
|
||
.search-icon {
|
||
width: 31rpx;
|
||
height: 31rpx;
|
||
flex-shrink: 0;
|
||
margin-right: 8rpx;
|
||
}
|
||
.search-input {
|
||
flex: 1;
|
||
min-width: 0;
|
||
font-size: 25rpx;
|
||
color: #333333;
|
||
}
|
||
.search-placeholder {
|
||
color: #929292;
|
||
}
|
||
/* 设计稿:搜索按钮 50x28px(96x54rpx),#FF6800,圆角 14px(27rpx),距边缘 2px(4rpx) */
|
||
.search-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 96rpx;
|
||
height: 54rpx;
|
||
flex-shrink: 0;
|
||
background: #ff6800;
|
||
border-radius: 27rpx;
|
||
font-size: 25rpx;
|
||
color: #ffffff;
|
||
}
|
||
</style>
|