目录
- 前言
- 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> |