二次封装elementui实现下拉搜索框

仿京东官网搜索框,二次封装elementui实现下拉搜索框(效果如图)

  • 实现鼠标点击输入框,显示历史记录栏、 热门搜索栏。
    • 历史记录显示5个,localstorage存本地,去重后显示在第一个(重复不显示),超出5个删除最后一个
    • 热门搜索栏默认显示10个
  • 实现模糊搜索,输入关键字可显示与输入内容关联内容,若搜索无此内容,显示“搜索:xxx”
  • 实现输入关联词,点击其他地方再回到搜索框,搜索框可显示上次输入内容

fix
20220812修复输入关联词后,点击再回到搜索框,删除不掉上次输入内容的bug
20220831修复多次点击,已输入内容变灰色

下拉模糊搜索.gif
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" version="1" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes"/>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="renderer" content="webkit" />
    <title>下拉搜索框 模糊搜索</title>
    <style>
      * {
        margin: 0px;
        padding: 0px;
        box-sizing: border-box;
      }
      [v-cloak] {
        display: none;
      }
      .el-input__icon {
        display: none;
      }
      .el-input__prefix {
        left: auto !important;
        right: 0 !important;
      }
      .el-select-group {
        display: flex;
        padding: 10px 0 10px;
      }
      .el-select-group__title {
        font-weight: 500;
        font-size: 14px;
        color: #111;
      }
      .el-select-group .el-select-dropdown__item {
        margin-left: 20px;
        max-width: 180px;
        height: 24px;
        line-height: 24px;
        background: #EDEDED;
        color: #666666;
        border-radius: 2px;
        text-align: center;
        margin-bottom: 10px;
      }
      .el-select-dropdown__wrap {
        max-height: auto !important;
      }
      .el-select-group__wrap:not(:last-of-type) {
        padding-bottom: 0;
      }
      .el-select-group__wrap:not(:last-of-type)::after {
        display: none;
      }
      .el-select-group .el-select-dropdown__item:hover{
        color: #e1251b;
      }
      .el-popper .popper__arrow {
        display: none;
      }
      .el-popper[x-placement^=bottom] {
        margin-top: 0
      }
      .el-input--prefix .el-input__inner {
        height: 54px;
        border-radius: 6px;
      }
      .el-select .el-input.is-focus .el-input__inner {
        border-color: #e1251b;
      }
      .search-empty {
        padding: 20px;
        font-size:14px;
        color: #666666;
        cursor: pointer;
      }
      .search-empty:hover {
        color: #e1251b;
      }
      .el-select .el-input__inner:hover {
        cursor: text !important;
      }
      .search-btn {
        width: 124px;
        height: 54px;
        background: #e1251b;
        color:#fff;
        border-radius: 0 6px 6px 0;
        border: 1px solid #e1251b;
      }
      .search-btn:hover {
        background-color: #c81623;
        color:#fff;
      }
    </style>
  </head>

  <body>
    <div id="app" v-cloak style="text-align: center;margin-top: 100px;">
      <template>
        <el-select
          filterable
          v-model="searchValue"
          placeholder="Search..."
          style="width: 614px;height: 54px;border-radius: 6px;"
          @focus="searchFocus"
          @click="searchFocus"
          @change="searcChange"
          ref="elSelec"
          :filter-method="filterMethod"
          @keyup.enter.native="onSearch">
          <template slot="prefix">
            <el-button @click="onSearch" icon="el-icon-search" class="search-btn">搜索</el-button>
          </template>
          <template slot="empty">
            <div class="search-empty" @click="onSearch">搜索 “{{this.searchValue}}”</div>
          </template>
          <div v-if="isShowHistroy">
            <el-option-group label="历史记录" style="margin-top: 30px;">
              <el-option v-for="(item, index) in historyOptions" :key="index" :label="item" :value="item"></el-option>
            </el-option-group>
            <el-option-group label="热门城市" >
              <div style="width: 614px;display:flex;flex-wrap:wrap;">
                <el-option v-for="(item, index) in hotOptions" :key="index" :label="item" :value="item"></el-option>
              </div>
            </el-option-group>
          </div>

          <div>
            <el-option v-for="(item, index) in options" :key="index" :label="item" :value="item"></el-option>
          </div>
        </el-select>
      </template>
    </div>
  </body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <script>
    var V = new Vue({
      el: "#app",
      data: function () {
        return {
          searchValue: '',
          isShowHistroy: false,
          historyOptions: [], // 历史搜索
          hotOptions: ['北京', '上海', '乌鲁木齐', '昆明', '南宁', '广州', '厦门', '西安', '长沙', '贵阳'], // 热门搜索
          options: [],
          // 词库
          optionsFilter: ['北京', '上海', '广州广州广州', '广州', '杭州', '西安', '昆明', '南宁', '贵州南宁', '南宁南宁北京', '南宁上海', '南宁广州广州广州', '广州', '杭州', '西安', '昆明', '南宁', '贵州'], // 联系词库
        }
      },
      created() {
      },
      mounted() {
        this.historyOptions = JSON.parse(localStorage.getItem("histroyOptions")) || []    
      },
      updated() {},
      destroyed() {},
      watch: {},
      computed: {},
      methods: {
        // 历史记录存本地
        saveLocalStorage(val) {
          if (val) {
            this.historyOptions.unshift(val)
            this.historyOptions = [...new Set(this.historyOptions)]
            if (this.historyOptions.length > 5) {
              this.historyOptions.pop()
            }
            localStorage.setItem('histroyOptions', JSON.stringify(this.historyOptions))
          }
        },
        // 搜索跳转
        onSearch() {
          console.log(this.searchValue)
          this.saveLocalStorage(this.searchValue)
          window.location.href = `test.html?keywork=${this.searchValue}`
        },
        // input获取焦点
        searchFocus(e) {
          let value = this.searchValue
          if (value) {
            // 已输入内容 重新赋值到搜素框
            setTimeout(() => {
              let input = this.$refs.elSelec.$children[0].$refs.input
              input.value = value
              let that = this
              // 监听input的是输入值变化
              input.oninput = function() {
                that filterMethod(this.value)
              }
            })
          } else {
            this.isShowHistroy = true
          }
        },
        // 选中
        searcChange(val) {
          this.isShowHistroy = false
          this.saveLocalStorage(val)
          window.location.href = `test.html?keywork=${val}`
        },
        // 自定义过滤
        filterMethod(val) {
          console.log(val, '输入的值')         
          if (val) {
            this.isShowHistroy = false
            this.searchValue = val
              let filterResult = []
              let originalData = JSON.parse(JSON.stringify(this.optionsFilter)) // 词库
              originalData.filter((item) => {
                  if (item.includes(val)) {
                      filterResult.push(item)
                  }
              })
              this.options = filterResult.length ? filterResult : []
          } else {
            this.options = []
            this.isShowHistroy = true
            this.searchValue = ''
          }
        },
      },
    });
  </script>
</html>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容