Vue利用flex布局实现TV端城市列表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue利用flex布局实现TV端城市列表相关的知识,希望对你有一定的参考价值。

前言

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: 140px;


.index-root-search-title-css
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom: 40px;


.search-bar-root .search-bar
background-color: #ffffff;
width: 1000px;
height: 100px;
display: flex;
justify-content: center;
border-radius: 8px;


.search-input
width: 780px;
border-radius: 8px;
font-size: 36px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #000000;
margin-left: 40px;
text-indent: 40px;


.index-root-search-image-view-css
position: absolute;
width: 32px;
height: 32px;
top: 35px;
bottom: 35px;
right: 0;
margin-right: 102px;
text-align: center;


.index-root-search-flex-view-css
display: flex;
flex-wrap: wrap;
flex-direction: row;
width: 1450px;
margin-left: 245px;
margin-right: 245px;
margin-top: 40px;


.index-root-search-text-view-css
font-size: 30px;
font-family: PingFangSC-Regular, PingFang SC;
color: #000000;
text-align: center;
font-weight: 400;
top: 0;
bottom: 0;
right: 0;
position: absolute;
margin-right: 30px;


.index-root-search-title-text-view-css
font-size: 70px;
font-family: PingFangSC-Regular, PingFang SC;
color: #ffffff;
text-align: center;
opacity: 1.0;


.search-city-button-view-css
width: 270px;
height: 100px;
background-color: rgba(0, 0, 0, .1);
margin-right: 20px;
margin-top: 40px;
border-radius: 11px;
border-width: 2px;
border-color: rgba(255, 255, 255, 0.1);
focus-background-color: #fff;


.search-city-button-view-css .city-sel-box
border-width: 2px;
border-color: #32C5FF;

复制代码

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: 20px" v-if="showHot && cityId===0">
<img src="@/assets/location.png" class="icon-location" showOnState="normal">
<img src="@/assets/location_hot_focus.png" 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: 1450px;
margin-left: 245px;
margin-right: 245px;
margin-top: 40px;


.index-root-search-text-view-css
font-size: 30px;
font-family: PingFangSC-Regular, PingFang SC;
color: #000000;
text-align: center;
font-weight: 400;
top: 0;
bottom: 0;
right: 0;
position: absolute;
margin-right: 30px;


.index-root-search-title-text-view-css
font-size: 70px;
font-family: PingFangSC-Regular, PingFang SC;
color: #ffffff;
text-align: center;
opacity: 1.0;


.search-city-button-view-css
width: 270px;
height: 100px;
background-color: rgba(0, 0, 0, .1);
margin-right: 20px;
margin-top: 40px;
border-radius: 11px;
border-width: 2px;
border-color: rgba(255, 255, 255, 0.1);
focus-background-color: #fff;


.search-city-button-view-css .city-sel-box
border-width: 2px;
border-color: #32C5FF;


.icon-location-reactive
position: absolute;
width: 26px;
height: 34px;
margin-left: 60px;
margin-top: 30px;
margin-bottom: 30px;


.icon-location
width: 26px;
height: 34px;
position: absolute;
left: 0;
top: 0;
z-index: 9;


.search-city-hot-text-iew-css
width: 270px;
height: 100px;
background-color: rgba(50, 197, 255, 0.1);
border-radius: 11px;
border: 2px solid #32C5FF;
font-size: 36px;
font-family: PingFangSC-Regular, PingFang SC;
text-align: center;
color: white;


.search-city-empty
margin-top: 40px;
width: 425px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-left: 535px;


.search-city-empty .icon-no-connect
width: 425px;
height: 307px;


.search-city-empty .empty-txt
font-size: 32px;
font-family: PingFangSC-Light, PingFang SC;
font-weight: 300;
color: #FFFFFF;
margin-top: 60px;

复制代码

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: 20px" v-if="showHot && cityId===0">
<img src="@/assets/location.png" class="icon-location" showOnState="normal">
<img src="@/assets/location_hot_focus.png" class="icon-location" showOnState="focused">
</div>
复制代码

6.设置焦点背景颜色和字体效果:

主要是设置:duplicateParentState="true"当文本获得焦点时颜色不受父布局影响,还可以设置焦点放大和带边框效果

:enableFocusBorder="true"//设置获得焦点时的边框
:focusScale="1.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: 20px" v-if="showHot && cityId===0">
<img src="@/assets/location.png" class="icon-location" showOnState="normal">
<img src="@/assets/location_hot_focus.png" 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 === 0">
<img src="@/assets/no_content.png" class="icon-no-connect"/>
<p class="empty-txt">没有搜索结果~</p>
</div>
</div>
</div>
<loading-view
style="width: 100px;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: #000000
,
focusHotTextColor:
type: String,
default: #00EFFF
,
textColor:
type: String,
default: #FFFFFF
,
textFontSize:
type: String,
default: 30px
,
textFontWeight:
type: Number,
default: 400
,
focusBackground:
orientation: TL_BR,//TOP_BOTTOM,TR_BL, RIGHT_LEFT, BR_TL, BOTTOM_TOP,BL_TR,LEFT_RIGHT,TL_BR,
cornerRadius: [40, 40, 40, 40],
normal: [#00000000, #00000000],
focused: [#F5F5F5, #F5F5F5],
,
,
data()
return
pageLoading: false,
text: search city,
search: ,
searchIcon: searchImage,
searchImageData: searchBackGroundImage,
searchTitle: "切换城市",
searchDefaultKeyWord: 搜索,
searchDefault: 请输入城市名称首字母或全拼,
focusColor: #f5f5f5,
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
, 500)
,
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: 1920px;
height: 1080px;
background-color: transparent;


.search-background-view-css
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: transparent;


.search-bar-root
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 140px;


.index-root-search-title-css
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom: 40px;


.search-bar-root .search-bar
background-color: #ffffff;
width: 1000px;
height: 100px;
display: flex;
justify-content: center;
border-radius: 8px;


.search-input
width: 780px;
border-radius: 8px;
font-size: 36px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #000000;
margin-left: 40px;
text-indent: 40px;


.index-root-search-image-view-css
position: absolute;
width: 32px;
height: 32px;
top: 35px;
bottom: 35px;
right: 0;
margin-right: 102px;
text-align: center;


.index-root-search-flex-view-css
display: flex;
flex-wrap: wrap;
flex-direction: row;
width: 1450px;
margin-left: 245px;
margin-right: 245px;
margin-top: 40px;


.index-root-search-text-view-css
font-size: 30px;
font-family: PingFangSC-Regular, PingFang SC;
color: #000000;
text-align: center;
font-weight: 400;
top: 0;
bottom: 0;
right: 0;
position: absolute;
margin-right: 30px;


.index-root-search-title-text-view-css
font-size: 70px;
font-family: PingFangSC-Regular, PingFang SC;
color: #ffffff;
text-align: center;
opacity: 1.0;


.search-city-button-view-css
width: 270px;
height: 100px;
background-color: rgba(0, 0, 0, .1);
margin-right: 20px;
margin-top: 40px;
border-radius: 11px;
border-width: 2px;
border-color: rgba(255, 255, 255, 0.1);
focus-background-color: #fff;


.search-city-button-view-css .city-sel-box
border-width: 2px;
border-color: #32C5FF;


.icon-location-reactive
position: absolute;
width: 26px;
height: 34px;
margin-left: 60px;
margin-top: 30px;
margin-bottom: 30px;


.icon-location
width: 26px;
height: 34px;
position: absolute;
left: 0;
top: 0;
z-index: 9;


.search-city-hot-text-iew-css
width: 270px;
height: 100px;
background-color: rgba(50, 197, 255, 0.1);
border-radius: 11px;
border: 2px solid #32C5FF;
font-size: 36px;
font-family: PingFangSC-Regular, PingFang SC;
text-align: center;
color: white;


.search-city-empty
margin-top: 40px;
width: 425px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-left: 535px;


.search-city-empty .icon-no-connect
width: 425px;
height: 307px;


.search-city-empty .empty-txt
font-size: 32px;
font-family: PingFangSC-Light, PingFang SC;
font-weight: 300;
color: #FFFFFF;
margin-top: 60px;

</style>
复制代码

11.实现的效果截图如下:

Vue利用flex布局实现TV端城市列表_vue

Vue利用flex布局实现TV端城市列表_flex布局_02

完整项目:​​点此下载​

以上是关于Vue利用flex布局实现TV端城市列表的主要内容,如果未能解决你的问题,请参考以下文章

h5移动端适配方案

前端vue实现圣杯布局flex布局浮动布局

前端vue实现圣杯布局flex布局浮动布局

vue组件--通讯录

vue之flex布局实现左滑删除

Vue 实现的音乐项目 music app 知识点总结分享