目录
- 前言
- 1.实现搜索布局代码:
- 2.搜索布局css样式代码:
- 3.城市列表布局代码:
- 4.城市列表css样式代码:
- 5.城市列表获取焦点的事件:
- 6.设置焦点背景颜色和字体效果:
- 7.搜索框输入事件:
- 8.搜索框获取焦点的事件:
- 9.默认弹出TV软键盘:
- 10.完整代码如下:
- 11.实现的效果截图如下:
- 总结
前言
vue中城市列表和搜索很常见,这篇博客就来说说咋实现搜索和城市列表
1.实现搜索布局代码:
<div class="search-bar">
<input class="search-input" v-model="citySearchResult" :placeholder="searchDefault" :key="searchTitle"
@endEditing="endEditing" :focusable="true" ref="searchInput" :duplicateParentState="true"
:enableFocusBorder="true"/>
<img class="index-root-search-image-view-css" :src="searchIcon">
<span class="index-root-search-text-view-css" ref="textViewCity">{{searchDefaultKeyWord}}</span>
</div>
2.搜索布局css样式代码:
.search-bar-root {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top:px;
}
.index-root-search-title-css {
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom:px;
}
.search-bar-root .search-bar {
background-color: #ffffff;
width:px;
height:px;
display: flex;
justify-content: center;
border-radius:px;
}
.search-input {
width:px;
border-radius:px;
font-size:px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight:;
color: #;
margin-left:px;
text-indent:px;
}
.index-root-search-image-view-css {
position: absolute;
width:px;
height:px;
top:px;
bottom:px;
right:;
margin-right:px;
text-align: center;
}
.index-root-search-flex-view-css {
display: flex;
flex-wrap: wrap;
flex-direction: row;
width:px;
margin-left:px;
margin-right:px;
margin-top:px;
}
.index-root-search-text-view-css {
font-size:px;
font-family: PingFangSC-Regular, PingFang SC;
color: #;
text-align: center;
font-weight:;
top:;
bottom:;
right:;
position: absolute;
margin-right:px;
}
.index-root-search-title-text-view-css {
font-size:px;
font-family: PingFangSC-Regular, PingFang SC;
color: #ffffff;
text-align: center;
opacity:.0;
}
.search-city-button-view-css {
width:px;
height:px;
background-color: rgba(, 0, 0, .1);
margin-right:px;
margin-top:px;
border-radius:px;
border-width:px;
border-color: rgba(, 255, 255, 0.1);
focus-background-color: #fff;
}
.search-city-button-view-css .city-sel-box {
border-width:px;
border-color: #C5FF;
}
3.城市列表布局代码:
<div class="index-root-search-flex-view-css" :clipChildren="false" ref="citySearch">
<div class="search-city-button-view-css"
v-for="(item,cityId) in hotCity" :focusable="true"
:key="cityId"
:ref="`hotRef${cityId}`" @focus="onFocus" :clipChildren="false">
<div class="icon-location-reactive" ref="searchLocation" :duplicateParentState="true" style="visibility: visible;margin-right:px" v-if="showHot && cityId===0">
<img src="@/assets/location.png" alt="" class="icon-location" showOnState="normal">
<img src="@/assets/location_hot_focus.png" alt="" class="icon-location" showOnState="focused">
</div>
<span class="search-city-hot-text-iew-css" :duplicateParentState="true" showOnState="focused"
ref="searchHotSelected"
:style="{focusColor: focusHotTextColor,fontSize: textFontSize,fontWeight: textFontWeight,}">{{item.cityName}}</span>
</div>
4.城市列表css样式代码:
.index-root-search-flex-view-css {
display: flex;
flex-wrap: wrap;
flex-direction: row;
width:px;
margin-left:px;
margin-right:px;
margin-top:px;
}
.index-root-search-text-view-css {
font-size:px;
font-family: PingFangSC-Regular, PingFang SC;
color: #;
text-align: center;
font-weight:;
top:;
bottom:;
right:;
position: absolute;
margin-right:px;
}
.index-root-search-title-text-view-css {
font-size:px;
font-family: PingFangSC-Regular, PingFang SC;
color: #ffffff;
text-align: center;
opacity:.0;
}
.search-city-button-view-css {
width:px;
height:px;
background-color: rgba(, 0, 0, .1);
margin-right:px;
margin-top:px;
border-radius:px;
border-width:px;
border-color: rgba(, 255, 255, 0.1);
focus-background-color: #fff;
}
.search-city-button-view-css .city-sel-box {
border-width:px;
border-color: #C5FF;
}
.icon-location-reactive {
position: absolute;
width:px;
height:px;
margin-left:px;
margin-top:px;
margin-bottom:px;
}
.icon-location {
width:px;
height:px;
position: absolute;
left:;
top:;
z-index:;
}
.search-city-hot-text-iew-css {
width:px;
height:px;
background-color: rgba(, 197, 255, 0.1);
border-radius:px;
border:px solid #32C5FF;
font-size:px;
font-family: PingFangSC-Regular, PingFang SC;
text-align: center;
color: white;
}
.search-city-empty {
margin-top:px;
width:px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-left:px;
}
.search-city-empty .icon-no-connect {
width:px;
height:px;
}
.search-city-empty .empty-txt {
font-size:px;
font-family: PingFangSC-Light, PingFang SC;
font-weight:;
color: #FFFFFF;
margin-top:px;
}
5.城市列表获取焦点的事件:
主要是在div设置:focusable="true"和@focus="onFocus"
<div class="search-city-button-view-css"
v-for="(item,cityId) in hotCity" :focusable="true"
:key="cityId"
:ref="`hotRef${cityId}`" @focus="onFocus" :clipChildren="false">
<div class="icon-location-reactive" ref="searchLocation" :duplicateParentState="true" style="visibility: visible;margin-right:px" v-if="showHot && cityId===0">
<img src="@/assets/location.png" alt="" class="icon-location" showOnState="normal">
<img src="@/assets/location_hot_focus.png" alt="" class="icon-location" showOnState="focused">
</div>
6.设置焦点背景颜色和字体效果:
主要是设置:duplicateParentState="true"当文本获得焦点时颜色不受父布局影响,还可以设置焦点放大和带边框效果
:enableFocusBorder="true"//设置获得焦点时的边框
:focusScale=".0"//设置焦点放大时的倍数
焦点效果的样式::style="{focusColor: focusHotTextColor,fontSize: textFontSize,fontWeight: textFontWeight,}
<span class="search-city-hot-text-iew-css" :duplicateParentState="true" showOnState="focused"
ref="searchHotSelected"
:style="{focusColor: focusHotTextColor,fontSize: textFontSize,fontWeight: textFontWeight,}">{{item.cityName}}</span>
7.搜索框输入事件:
//输入内容之后请求城市列表接口刷新数据
endEditing(e) {
console.log("--resultData--", this.citySearchResult)
},
8.搜索框获取焦点的事件:
onFocus(e) {
this.focused = e.isFocused;
this.$emit("onButtonFocused", e.isFocused);
},
9.默认弹出TV软键盘:
mounted() {
this.hotCity = hotCity;
this.showHot = true;
this.pageLoading = true
//弹出软键盘
this.$refs.searchInput.focus()
//搜索框默认获取焦点
this.setHideLoading()
},
10.完整代码如下:
<template>
<div class="index-root-search-view-css" :clipChildren="false">
<img class="search-background-view-css" :src="searchImageData"/>
<div class="search-bar-root">
<div class="index-root-search-title-css">
<span class="index-root-search-title-text-view-css"> {{ searchTitle }}</span>
</div>
<div class="search-bar">
<input class="search-input" v-model="citySearchResult" :placeholder="searchDefault" :key="searchTitle"
@endEditing="endEditing" :focusable="true" ref="searchInput" :duplicateParentState="true"
:enableFocusBorder="true"/>
<img class="index-root-search-image-view-css" :src="searchIcon">
<span class="index-root-search-text-view-css" ref="textViewCity">{{searchDefaultKeyWord}}</span>
</div>
<div class="index-root-search-flex-view-css" :clipChildren="false" ref="citySearch">
<div class="search-city-button-view-css"
v-for="(item,cityId) in hotCity" :focusable="true"
:key="cityId"
:ref="`hotRef${cityId}`" @focus="onFocus" :clipChildren="false">
<div class="icon-location-reactive" ref="searchLocation" :duplicateParentState="true" style="visibility: visible;margin-right:px" v-if="showHot && cityId===0">
<img src="@/assets/location.png" alt="" class="icon-location" showOnState="normal">
<img src="@/assets/location_hot_focus.png" alt="" class="icon-location" showOnState="focused">
</div>
<span class="search-city-hot-text-iew-css" :duplicateParentState="true" showOnState="focused"
ref="searchHotSelected"
:style="{focusColor: focusHotTextColor,fontSize: textFontSize,fontWeight: textFontWeight,}">{{item.cityName}}</span>
</div>
<div class="search-city-empty" v-if="hotCity.length ===">
<img src="@/assets/no_content.png" alt="" class="icon-no-connect"/>
<p class="empty-txt">没有搜索结果~</p>
</div>
</div>
</div>
<loading-view
style="width:px;height: 100px;position: absolute;left:960px;right:960px;top:500px;bottom:500px;align-self:
center;align-items: center;justify-content: center" v-show="pageLoading"/>
</div>
</template>
<script>
import searchImage from "@/assets/search_focus.png";
import searchBackGroundImage from "@/assets/index-bg-qing.jpg";
import {hotCity} from '@/views/contsants';
import {ESLaunchManager} from "@extscreen/es-core";
export default {
name: "city_list",
props: {
searchKeyWord: {
type: String,
default: '',
},
focusTextColor: {
type: String,
default: '#'
},
focusHotTextColor: {
type: String,
default: '#EFFF'
},
textColor: {
type: String,
default: '#FFFFFF'
},
textFontSize: {
type: String,
default: 'px'
},
textFontWeight: {
type: Number,
default:
},
focusBackground: {
orientation: 'TL_BR',//TOP_BOTTOM,TR_BL, RIGHT_LEFT, BR_TL, BOTTOM_TOP,BL_TR,LEFT_RIGHT,TL_BR,
cornerRadius: [, 40, 40, 40],
normal: ['#', '#00000000'],
focused: ['#FF5F5', '#F5F5F5'],
},
},
data() {
return {
pageLoading: false,
text: 'search city',
search: '',
searchIcon: searchImage,
searchImageData: searchBackGroundImage,
searchTitle: "切换城市",
searchDefaultKeyWord: '搜索',
searchDefault: '请输入城市名称首字母或全拼',
focusColor: '#ff5f5',
citySearchResult: "",
hotCity: [],
cityName: "",
cityId: "",
showHot: true,
params: '',
}
},
activated() {
},
deactivated() {
this.resetModel()
},
mounted() {
this.hotCity = hotCity;
this.showHot = true;
this.pageLoading = true
//弹出软键盘
this.$refs.searchInput.focus()
//搜索框默认获取焦点
this.setHideLoading()
},
methods: {
setHideLoading() {
setTimeout(() => {
this.pageLoading = false
},)
},
onFocus(e) {
this.focused = e.isFocused;
this.$emit("onButtonFocused", e.isFocused);
},
//输入内容之后请求城市
endEditing(e) {
console.log("--resultData--", this.citySearchResult)
},
onBackPressed() {
ESLaunchManager.finishESPage();
},
resetModel() {
this.citySearchResult = "";
this.hotCity = [];
this.pageLoading = false;
this.searchTitle = "";
this.searchDefaultKeyWord = "";
this.searchDefault = "";
},
}
}
</script>
<style scoped>
.index-root-search-view-css {
width:px;
height:px;
background-color: transparent;
}
.search-background-view-css {
position: absolute;
left:;
top:;
right:;
bottom:;
background-color: transparent;
}
.search-bar-root {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top:px;
}
.index-root-search-title-css {
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom:px;
}
.search-bar-root .search-bar {
background-color: #ffffff;
width:px;
height:px;
display: flex;
justify-content: center;
border-radius:px;
}
.search-input {
width:px;
border-radius:px;
font-size:px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight:;
color: #;
margin-left:px;
text-indent:px;
}
.index-root-search-image-view-css {
position: absolute;
width:px;
height:px;
top:px;
bottom:px;
right:;
margin-right:px;
text-align: center;
}
.index-root-search-flex-view-css {
display: flex;
flex-wrap: wrap;
flex-direction: row;
width:px;
margin-left:px;
margin-right:px;
margin-top:px;
}
.index-root-search-text-view-css {
font-size:px;
font-family: PingFangSC-Regular, PingFang SC;
color: #;
text-align: center;
font-weight:;
top:;
bottom:;
right:;
position: absolute;
margin-right:px;
}
.index-root-search-title-text-view-css {
font-size:px;
font-family: PingFangSC-Regular, PingFang SC;
color: #ffffff;
text-align: center;
opacity:.0;
}
.search-city-button-view-css {
width:px;
height:px;
background-color: rgba(, 0, 0, .1);
margin-right:px;
margin-top:px;
border-radius:px;
border-width:px;
border-color: rgba(, 255, 255, 0.1);
focus-background-color: #fff;
}
.search-city-button-view-css .city-sel-box {
border-width:px;
border-color: #C5FF;
}
.icon-location-reactive {
position: absolute;
width:px;
height:px;
margin-left:px;
margin-top:px;
margin-bottom:px;
}
.icon-location {
width:px;
height:px;
position: absolute;
left:;
top:;
z-index:;
}
.search-city-hot-text-iew-css {
width:px;
height:px;
background-color: rgba(, 197, 255, 0.1);
border-radius:px;
border:px solid #32C5FF;
font-size:px;
font-family: PingFangSC-Regular, PingFang SC;
text-align: center;
color: white;
}
.search-city-empty {
margin-top:px;
width:px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-left:px;
}
.search-city-empty .icon-no-connect {
width:px;
height:px;
}
.search-city-empty .empty-txt {
font-size:px;
font-family: PingFangSC-Light, PingFang SC;
font-weight:;
color: #FFFFFF;
margin-top:px;
}
</style>