vue3+element-plus+js 实现快速搜索并且关键字高亮

代码项目助手 毕业设计 1

点击搜索按钮,弹出模态框。 下拉框选择选项,然后进行相应查询。 查询出来的数据,点击后跳转相应页面关键字所在地。

<template>
  <span v-if="theme.showSearch">
    <vab-icon icon="search-line" @click="openDialog" />
    <!-- 模态框 -->
    <el-dialog v-model="state.dialogVisible" :width="'40%'">
      <el-form :model="state.queryForm" @submit.prevent>
        <el-form-item label-width="0">
          <!-- <el-autocomplete
            v-model="state.queryForm.searchWord"
            v-focus
            :fetch-suggestions="querySearchAsync"
            select-when-unmatched
            @select="handleSelect"
          >
            <template #prefix><vab-icon icon="search-line" /></template> -->
          <!-- 快速搜索 -->
          <el-input
            v-model="state.queryForm.searchWord"
            v-focus
            placeholder="快速搜索"
            class="page_speed_1655116835"
          >
            <template #prepend>
              <el-select v-model="select">
                <el-option label="部件" :value="1" />
                <el-option label="文档" :value="2" />
                <el-option label="CAD文档" :value="3" />
                <el-option label="申请单" :value="4" />
                <el-option label="ECN" :value="5" />
              </el-select>
            </template>
            <template #append>
              <el-button icon="Search" @click="quickSearch" />
            </template>
          </el-input>
          <!-- </el-autocomplete> -->
        </el-form-item>
      </el-form>
    </el-dialog>
  </span>
</template>
<script>
  import { computed, defineComponent, onMounted, reactive, toRefs } from 'vue'
  import { useStore } from 'vuex'
  import { getList } from '@/api/search'
  export default defineComponent({
    name: 'VabSearch',
    directives: {
      focus: {
        mounted(el) {
          el.querySelector('input').focus()
        },
      },
    },
    setup() {
      const store = useStore()
      const theme = computed(() => store.getters['settings/theme'])
      // let timeout = null
      const state = reactive({
        input1: '',
        input2: '',
        input3: '',
        input4: '',
        input5: '',
        input6: '',
        input7: '',
        input8: '',
        input9: '',
        select: 1,
        dialogVisible: false,
        queryForm: {
          searchWord: '',
        },
        restaurants: [],
      })
      const loadAll = async () => {
        const {
          data: { list },
        } = await getList()
        state.restaurants = list
      }
      onMounted(() => {
        if (theme.value.showSearch) loadAll()
      })
      const openDialog = () => {
        state.queryForm.searchWord = ''
        state.dialogVisible = true
      }
      // 模糊查询
      const quickSearch = () => {
        console.log(quickSearch)
      }
      // const querySearchAsync = (queryString, cb) => {
      //   const restaurants = state.restaurants
      //   const results = queryString
      //     ? restaurants.filter(createFilter(queryString))
      //     : restaurants
      //   clearTimeout(timeout)
      //   timeout = setTimeout(() => {
      //     cb(results)
      //   }, 500)
      // }
      // const createFilter = (queryString) => (state) =>
      //   state.value.includes(queryString.toLowerCase())
      // const handleSelect = (item) => {
      //   if (item.url) {
      //     window.open(item.url)
      //   } else {
      //     window.open(`https://www.baidu.com/s?wd=${item.value}`)
      //   }
      // }
      return {
        theme,
        state,
        ...toRefs(state),
        openDialog,
        quickSearch,
        // createFilter,
        // handleSelect,
        // querySearchAsync,
      }
    },
  })
</script>
<style lang="scss" scoped>
  :deep() {
    .el-input {
      width: 180px;
      &:first-child {
        margin-right: 10px;
        margin-bottom: 10px;
      }
      & + .el-input {
        margin-right: 10px;
        margin-bottom: 10px;
        margin-left: 0;
      }
    }
    .el-textarea {
      width: 180px;
    }
    .el-select {
      .el-input {
        width: 100px;
        margin-bottom: 0;
      }
    }
  }
</style>
运行结果及报错内容

目前没什么思路

我的解答思路和尝试过的方法

希望可以贴代码的时候,多写点注释,或者提供思路

我想要达到的结果

下拉框选择选项,然后进行相应查询。实现快速搜索并且关键字高亮 查询出来的数据,点击后跳转相应页面关键字所在地。 由于没有后台数据,一切都是模拟,所以数据随意

回复

共2条回复 我来回复
  • 毕设港湾
    这个人很懒,什么都没有留下~
    评论

    拿官网远程搜索例子稍改了一下 主要思路就是搜索的数据,匹配关键字替换成包裹span标签,再v-html渲染

    <template>
     <div>
      <h1>test</h1>
      <el-autocomplete
       v-model="state"
       :fetch-suggestions="querySearchAsync"
       placeholder="Please input"
       @select="handleSelect">
       <template #default="{ item }">
        <div v-html="item.value"></div>
       </template>
      </el-autocomplete>
     </div>
    </template>
    <script lang="ts">
    import { defineComponent, ref, onMounted } from 'vue'
    export default defineComponent({
     setup() {
      const links = ref([])
      const loadAll = () => {
       return [
        { value: 'vue', link: 'https://github.com/vuejs/vue' },
        { value: 'element', link: 'https://github.com/ElemeFE/element' },
        { value: 'cooking', link: 'https://github.com/ElemeFE/cooking' },
        { value: 'mint-ui', link: 'https://github.com/ElemeFE/mint-ui' },
        { value: 'vuex', link: 'https://github.com/vuejs/vuex' },
        { value: 'vue-router', link: 'https://github.com/vuejs/vue-router' },
        { value: 'babel', link: 'https://github.com/babel/babel' },
       ]
      }
      let timeout
      const querySearchAsync = (queryString: string, cb: (arg: any) => void) => {
       const list = JSON.parse(JSON.stringify(links.value))
       const results = queryString
        ? list.filter(createFilter(queryString))
        : list
       console.log(queryString)
       if (queryString) {
        // 匹配关键字
        let replaceReg = new RegExp(queryString, 'g')
        results.forEach(item => {
          // 替换html
          let replaceString = `<span >${queryString}</span>`
          // 开始替换
          item.value = item.value.replace(replaceReg, replaceString);
        })
       }
       clearTimeout(timeout)
       timeout = setTimeout(() => {
        cb(results)
       }, 1000 * Math.random())
      }
      const createFilter = (queryString: string) => {
       return (restaurant) => {
        return (
         restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) !== -1
        )
       }
      }
      const handleSelect = (item) => {
       console.log(item)
      }
      onMounted(() => {
       links.value = loadAll()
      })
      return {
       links,
       state: ref(''),
       querySearchAsync,
       createFilter,
       loadAll,
       handleSelect,
      }
     },
    })
    </script>
    <style>
    .search-text {
     color: red;
     font-weight: 700;
    }
    </style>
    
    0条评论
  • 源码码头网
    这个人很懒,什么都没有留下~
    评论

    用element-ui-plus的自动补全输入框,然后自定义建议内容插槽,就能实现关键词高亮了 你可以用关键词分割字符串然后显示

    这里的arr是你远程获取到的快速搜索推荐项
    <template v-for="(content,contentIndex) in arr.split(keyWord)" :key="contentIndex">  
                <span class="c1a_83bd_bd98ec9 keyword" v-if="contentIndex !== 0">{{ keyWord }}</span>
              <span>{{ content }}</span>
     </template>
    
    0条评论

发表回复

登录后才能评论