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

news2024/11/27 16:46:58

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" 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: 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" 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="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" 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 === 0">
          <img src="@/assets/no_content.png" alt="" 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.实现的效果截图如下:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/3927.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java【数组】定义与使用,什么是引用类型你知道吗

文章目录前言一、数组的基本概念1.什么是数组2.数组的创建和初始化1.数组的创建2. 数组的初始化3.数组的使用4.遍历数组&#xff08;两种方式&#xff09;二、数组是引用类型1.初识JVM内存分配2.引用类型3.认识null三、数组的应用场景1.保存数据2.作为方法的参数1.参数传基本数…

STM32F407ZGT6|SPI主从模式

功能&#xff1a;主机发送数据0x34–>从机接收数据–>通过串口将数据发送出去–>串口猎人显示0x34 必备知识点 1、SPI串行外设接口特点 高速、全双工、同步、串行高速&#xff1a;发送数据的速度很快全双工&#xff1a;两设备可同时双向通信&#xff08;接收与发送&…

STM32 CAN过滤器标识符学习笔记

最近看了下STM32 CAN 通讯其中标示符过滤器设置大有讲究。特别是你要使用ST库函数时&#xff0c;当过滤器工作在屏蔽模式下&#xff0c;并且你把屏蔽位设了1也就是标示符对应位必须全部匹配才能通过&#xff0c;这是由其要小心。 举个例子吧&#xff0c;过滤器长度为32位&…

【MindSpore易点通】在开发环境中如何使用MindInsight在线调试器

背景信息 在使用开发环境训练任务过程中&#xff0c;为方便开发人员更形象地观察到实时训练任务中的数值变化情况以分析精度问题&#xff0c;ModelArts在线调节器应运而生。与离线调试器的区别在于&#xff0c;离线调试器只能待整个任务运行完成后&#xff08;收集到整个任务过…

【机器学习大杀器】Stacking堆叠模型

1.前言 Kaglle比赛中使用Stacking模型是非常常见的大杀器&#xff0c;这是为什么呢&#xff1f; 【机器学习大杀器】Stacking堆叠模型 1.前言 2.Model 3: Stacking model 2.1 description of the algorithms: 2.2 interpretation of the estimated models: 3. Extend 3.1 …

终于盼到了,Python 数据科学速查表中文版来了

近几年以来&#xff0c;Python 的应用场景越来越多&#xff0c;几乎可以应用于自然科学、工程技术、金融、通信和商业等各种领域。究其原因在于 Python 的简单易学、功能强大。 想系统地学点东西&#xff0c;发现很多不错的技术文档都是英文资料&#xff0c;发现英文竟然成为了…

数据结构考研第六章——图(内含动图)

大纲要求&#xff1a;图的相关算法相对较多&#xff0c;通常只要求掌握其基本思想和实现步骤&#xff0c;而算法的具体实现不是重点。 一、图的基本概念 图的概念&#xff1a;图G由顶点集V和边集E组成的&#xff0c;记为G&#xff08;V&#xff0c;E&#xff09;有向图&#x…

6_显示登录信息以及上传图片

目录一 显示登录信息二 账号设置修改用户图片一 显示登录信息 实现思路 书写一个拦截器 loginTicketInterceptor 在 preHandle 方法中获取用户发送请求时携带的 cookie书写一个专门获取cookie的工具类 CookieUtil查数据库,数据库是否存在该 ticket,判断该凭证是否有效,-凭证是…

【论文阅读】EDPLVO: Efficient Direct Point-Line Visual Odometry

一、公式及符号约定 这篇论文是将直接法的残差计算从点扩展到了线段&#xff0c;所以一些符号在第三章的部分提前做了约定。用Π表示投影的函数&#xff0c;也就是用像素坐标和内参矩阵以及深度信息&#xff0c;投影出点的空间坐标&#xff0c;反之Π-1表示的是将空间坐标投影…

Git使用详细教程

1. cmd面板的常用命令 clear&#xff1a;清屏cd 文件夹名称----进入文件夹cd … 进入上一级目录(两个点)dir 查看当前目录下的文件和文件夹(全拼:directory)Is 查看当前目录下的文件和文件夹touch 文件名----创建文件echo 内容 > 创建文件名----创建文件并写入内容rm 文件名…

基于udp实现回显服务器,翻译服务器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 udp socket 要掌握的类&#xff1a; 1.DatagramSocket 2.DatagramPacket 一、udp版本回显服务器 服务端&#xff1a; 完整代码 客户端&#xff1a; 完整代码 udp版本翻译…

Spring注入和生命周期

目录 获取Bean对象&#xff08;对象装配&#xff09; 属性注入 构造注入 Setter注入 三种注入的优缺点分析 注入的注解&#xff1a; 一个类型多个bean对象的注入方式 1.让变量名等于bean的id 2.用Resource注解&#xff08;name“bean的id”&#xff09; 3.用Qualif…

Java 核心技术 0 —— Class加载 和 运行时数据区域

JVM 是 字节码的运行环境&#xff0c;负责装载class到JVM内部&#xff0c;解释编译为对应平台的机器码指令进行执行&#xff0c;对于JVM设计有权威的定义规范&#xff0c;了解 JVM 类加载各部的主要功能 和 运行时数据区域组成 很有意义。 磁盘上有一个.java文件&#xff0c;通…

【目标检测】swin-transformer训练自己的数据集

文章目录1. 数据集的制作1.1. Labelme制作数据集1.2 COCO数据集格式2. 配置swin-transformer3. 训练自己的数据集4. 训练5.参考链接1. 数据集的制作 1.1. Labelme制作数据集 pip install labelme然后在桌面搜索框中找到labelme&#xff0c;然后打开&#xff0c;或者直接在命令…

Python 工匠 第一章 变量与注释

1.1 基础知识 1.1.1 变量常见用法 Python 是一门动态类型的语言&#xff0c;因此无须提前声明变量类型&#xff1b;并且由于其是弱类型语言&#xff0c;即可以更改其变量类型。动态类型语言/弱类型语言 a 10 # 不需要提前声明变量类型 a "a" # 可以更改其变量类…

【架构师】解决方案架构师常用的5种类型架构图

0. 背景 在给不同部门的同学讲解系统时&#xff0c;如果用手势解释解决方案&#xff0c;还有很多“这块和这块通过...”在解释复杂的概念时&#xff0c;大部分人都会晕。我们需要一个视觉效果。有人说一个架构图不就行了吗&#xff1f;但架构图不是一个“放之四海而皆准”的解决…

一、springcloud-eureka服务注册与发现

SpringCloud简介 Spring Cloud 为开发者提供了工具来快速构建分布式系统中的一些常见模式&#xff08;例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话&#xff0c;集群状态&#xff09;。分布式系统的协调导致了样板…

04 Vue属性配置

1、ref属性 App.vue代码&#xff1a; <template><div><h1 v-text"msg" ref"myTitle"></h1><button click"showDom">点我输出上方的DOM元素</button><school ref"school" id"sch"/&…

Node.js | Express+MongoDB 实现简易用户管理系统(一)(项目搭建 | RESTful API架构 | 前后端交互)

&#x1f5a5;️ NodeJS专栏&#xff1a;Node.js从入门到精通 &#x1f5a5;️ 博主的前端之路&#xff08;源创征文一等奖作品&#xff09;&#xff1a;前端之行&#xff0c;任重道远&#xff08;来自大三学长的万字自述&#xff09; &#x1f5a5;️ TypeScript知识总结&…

【javaEE】多线程进阶(Part1 锁策略、CAS、synchronized )

目录前言/补充4. 描述一下线程池的执行流程和拒绝策略有哪些&#xff1f;【面试题&#xff01;】一、常见锁策略一&#xff09;乐观锁VS悲观锁二&#xff09;读写锁VS普通互斥锁三&#xff09;重量级锁VS轻量级锁四&#xff09;自旋锁VS挂起等待锁五&#xff09;公平锁VS非公平…