287 lines
6.1 KiB
Vue
287 lines
6.1 KiB
Vue
|
<template>
|
||
|
<view class="tui-searchbar__box" :style="{ backgroundColor: backgroundColor, padding: padding }">
|
||
|
<slot></slot>
|
||
|
<view class="tui-search-bar__form" :style="{height: height}">
|
||
|
<view class="tui-search-bar__box"
|
||
|
:class="{'tui-searchbar__blur':!isFocus && !searchState && showLabel && !disabled}"
|
||
|
:style="{ height: height, borderRadius: radius, backgroundColor: inputBgColor }" v-if="showInput">
|
||
|
<icon class="tui-icon-search" type="search" :size="searchSize"></icon>
|
||
|
<input type="text" class="tui-search-bar__input" :placeholder="placeholder" :value="valueTxt"
|
||
|
:focus="isFocus" :disabled="disabled" confirm-type="search" @blur="inputBlur" @focus="inputFocus"
|
||
|
@input="inputChange" @confirm="search" />
|
||
|
<icon type="clear" :size="clearSize" class="tui-icon-clear" v-if="valueTxt.length > 0 && !disabled"
|
||
|
@tap.stop="clearInput"></icon>
|
||
|
</view>
|
||
|
<view class="tui-search-bar__label"
|
||
|
:style="{height: height, borderRadius: radius, backgroundColor: inputBgColor }"
|
||
|
v-if="!isFocus && !searchState && showLabel" @tap="tapShowInput">
|
||
|
<icon class="tui-icon-search" type="search" :size="searchSize"></icon>
|
||
|
<text class="tui-search-bar__text">{{ placeholder }}</text>
|
||
|
</view>
|
||
|
</view>
|
||
|
<view v-if="cancel && searchState && !valueTxt" class="tui-search-bar__cancel-btn"
|
||
|
:style="{ color: cancelColor }" @tap="hideInput">{{ cancelText }}</view>
|
||
|
<view v-if="valueTxt && !disabled && searchState" class="tui-search-bar__cancel-btn"
|
||
|
:style="{ color: getSearchColor }" @tap="search">{{ searchText }}</view>
|
||
|
</view>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
//默认高度52px
|
||
|
export default {
|
||
|
name: 'tuiSearchbar',
|
||
|
emits: ['clear', 'focus', 'blur', 'click', 'cancel', 'input', 'search'],
|
||
|
props: {
|
||
|
//搜索栏背景色
|
||
|
backgroundColor: {
|
||
|
type: String,
|
||
|
default: '#ededed'
|
||
|
},
|
||
|
//搜索栏padding
|
||
|
padding: {
|
||
|
type: String,
|
||
|
default: '16rpx 20rpx'
|
||
|
},
|
||
|
//input框高度
|
||
|
height: {
|
||
|
type: String,
|
||
|
default: '72rpx'
|
||
|
},
|
||
|
radius: {
|
||
|
type: String,
|
||
|
default: '8rpx'
|
||
|
},
|
||
|
//input框背景色
|
||
|
inputBgColor: {
|
||
|
type: String,
|
||
|
default: '#fff'
|
||
|
},
|
||
|
focus: {
|
||
|
type: Boolean,
|
||
|
default: false
|
||
|
},
|
||
|
placeholder: {
|
||
|
type: String,
|
||
|
default: '请输入搜索关键词'
|
||
|
},
|
||
|
value: {
|
||
|
type: String,
|
||
|
default: ''
|
||
|
},
|
||
|
//input是否禁用
|
||
|
disabled: {
|
||
|
type: Boolean,
|
||
|
default: false
|
||
|
},
|
||
|
cancelText: {
|
||
|
type: String,
|
||
|
default: '取消'
|
||
|
},
|
||
|
cancelColor: {
|
||
|
type: String,
|
||
|
default: '#888'
|
||
|
},
|
||
|
cancel: {
|
||
|
type: Boolean,
|
||
|
default: true
|
||
|
},
|
||
|
searchText: {
|
||
|
type: String,
|
||
|
default: '搜索'
|
||
|
},
|
||
|
searchColor: {
|
||
|
type: String,
|
||
|
default: ''
|
||
|
},
|
||
|
//是否显示占位标签
|
||
|
showLabel: {
|
||
|
type: Boolean,
|
||
|
default: true
|
||
|
},
|
||
|
//是否显示输入框
|
||
|
showInput: {
|
||
|
type: Boolean,
|
||
|
default: true
|
||
|
}
|
||
|
},
|
||
|
computed: {
|
||
|
getSearchColor() {
|
||
|
return this.searchColor || (uni && uni.$tui && uni.$tui.color.primary) || '#1A73E8'
|
||
|
}
|
||
|
},
|
||
|
created() {
|
||
|
this.valueTxt = this.value;
|
||
|
this.isFocus = this.focus;
|
||
|
if (this.focus || this.valueTxt.length > 0) {
|
||
|
this.searchState = true;
|
||
|
}
|
||
|
this.clearSize = Math.ceil(uni.upx2px(30))
|
||
|
this.searchSize = Math.ceil(uni.upx2px(26))
|
||
|
},
|
||
|
watch: {
|
||
|
value(val) {
|
||
|
this.valueTxt = val;
|
||
|
}
|
||
|
},
|
||
|
data() {
|
||
|
return {
|
||
|
searchState: false,
|
||
|
isFocus: false,
|
||
|
valueTxt: '',
|
||
|
clearSize: 15,
|
||
|
searchSize: 13
|
||
|
};
|
||
|
},
|
||
|
methods: {
|
||
|
clearInput() {
|
||
|
this.valueTxt = '';
|
||
|
// #ifdef MP-TOUTIAO || MP-WEIXIN
|
||
|
this.isFocus = false;
|
||
|
uni.hideKeyboard()
|
||
|
// #endif
|
||
|
// #ifndef MP-TOUTIAO || MP-WEIXIN
|
||
|
this.isFocus = true;
|
||
|
// #endif
|
||
|
this.$emit('clear');
|
||
|
},
|
||
|
inputFocus(e) {
|
||
|
if (!this.showLabel) {
|
||
|
this.searchState = true
|
||
|
} else {
|
||
|
// #ifdef H5 || MP-ALIPAY
|
||
|
this.tapShowInput();
|
||
|
// #endif
|
||
|
}
|
||
|
this.$emit('focus', e.detail);
|
||
|
},
|
||
|
inputBlur(e) {
|
||
|
this.isFocus = false;
|
||
|
this.$emit('blur', e.detail);
|
||
|
},
|
||
|
tapShowInput() {
|
||
|
if (!this.disabled && this.showInput) {
|
||
|
this.searchState = true;
|
||
|
setTimeout(() => {
|
||
|
this.isFocus = true;
|
||
|
}, 20)
|
||
|
}
|
||
|
this.$emit('click', {});
|
||
|
},
|
||
|
|
||
|
hideInput() {
|
||
|
this.searchState = false;
|
||
|
this.isFocus = false;
|
||
|
uni.hideKeyboard()
|
||
|
this.$emit('cancel', {});
|
||
|
},
|
||
|
inputChange(e) {
|
||
|
this.valueTxt = e.detail.value;
|
||
|
this.$emit('input', e.detail);
|
||
|
},
|
||
|
search() {
|
||
|
this.$emit('search', {
|
||
|
value: this.valueTxt
|
||
|
});
|
||
|
},
|
||
|
reset() {
|
||
|
this.searchState = false;
|
||
|
this.isFocus = false;
|
||
|
this.valueTxt = '';
|
||
|
uni.hideKeyboard()
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
</script>
|
||
|
|
||
|
<style scoped>
|
||
|
.tui-searchbar__box {
|
||
|
width: 100%;
|
||
|
position: relative;
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
box-sizing: border-box;
|
||
|
}
|
||
|
|
||
|
.tui-search-bar__form {
|
||
|
position: relative;
|
||
|
-webkit-box-flex: 1;
|
||
|
-webkit-flex: auto;
|
||
|
flex: auto;
|
||
|
}
|
||
|
|
||
|
.tui-search-bar__box {
|
||
|
width: 100%;
|
||
|
padding-left: 20rpx;
|
||
|
padding-right: 16rpx;
|
||
|
box-sizing: border-box;
|
||
|
z-index: 1;
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
/* #ifdef H5 */
|
||
|
opacity: 1;
|
||
|
/* #endif */
|
||
|
}
|
||
|
|
||
|
/* #ifdef H5 || MP-ALIPAY */
|
||
|
.tui-searchbar__blur {
|
||
|
position: relative;
|
||
|
opacity: 0;
|
||
|
z-index: 3;
|
||
|
}
|
||
|
|
||
|
/* #endif */
|
||
|
|
||
|
.tui-search-bar__box .tui-search-bar__input {
|
||
|
padding: 0 16rpx;
|
||
|
width: 100%;
|
||
|
border: 0;
|
||
|
font-size: 28rpx;
|
||
|
box-sizing: content-box;
|
||
|
background: transparent;
|
||
|
}
|
||
|
|
||
|
.tui-search-bar__box .tui-search-bar__input:focus {
|
||
|
outline: none;
|
||
|
}
|
||
|
|
||
|
.tui-search-bar__box .tui-icon-search {
|
||
|
flex-shrink: 0;
|
||
|
}
|
||
|
|
||
|
.tui-search-bar__box .tui-icon-clear {
|
||
|
margin-left: 4rpx;
|
||
|
flex-shrink: 0;
|
||
|
}
|
||
|
|
||
|
.tui-search-bar__label {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
right: 0;
|
||
|
bottom: 0;
|
||
|
left: 0;
|
||
|
z-index: 2;
|
||
|
font-size: 0;
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
justify-content: center;
|
||
|
/* #ifdef H5 */
|
||
|
cursor: pointer;
|
||
|
/* #endif */
|
||
|
}
|
||
|
|
||
|
.tui-search-bar__cancel-btn {
|
||
|
font-size: 30rpx;
|
||
|
margin-left: 16rpx;
|
||
|
line-height: 56rpx;
|
||
|
white-space: nowrap;
|
||
|
flex-shrink: 0;
|
||
|
}
|
||
|
|
||
|
.tui-search-bar__text {
|
||
|
display: inline-block;
|
||
|
font-size: 28rpx;
|
||
|
vertical-align: middle;
|
||
|
padding-left: 12rpx;
|
||
|
color: rgba(0, 0, 0, 0.5);
|
||
|
}
|
||
|
</style>
|