当前位置: 首页>数据库>正文

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

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

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

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

二次封装elementui实现下拉搜索框,第1张
下拉模糊搜索.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>
      <template>
        <el-select
          filterable
          v-model="searchValue"
          placeholder="Search..."
         
          @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="历史记录">
              <el-option v-for="(item, index) in historyOptions" :key="index" :label="item" :value="item"></el-option>
            </el-option-group>
            <el-option-group label="热门城市" >
              <div>
                <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>


https://www.xamrdz.com/database/6v61994299.html

相关文章: