vue 实现搜索功能-高亮+定位+滚动的效果

本文介绍了如何在Vue3项目中结合TypeScript和Antd4.0构建一个具有搜索高亮功能的组件,包括数据渲染、关键词插入以及实现全文锚点的动态移动和定位。
摘要由CSDN通过智能技术生成

vue3 +ts +antd4.0

具体功能如图

在这里插入图片描述


前言

大体逻辑:
1、数据渲染;直接利用html进行渲染,搜索高亮一般都是查看类,依次数据不做其他处理,后端返回数据直接用,后端数据来源,一般为富文本来源;
2、关键词插入,修改源数据标签,进行高亮展示;
3、获取总em标签数量、设置动态移动变量
4、设置动态移动,并利用id进行锚点定位

话不多说,直接看代码;

 <div class="knowledgeContent">
          <a-input-search
            v-model:value="searchValue"
            placeholder="请输入关键字"
            style="width: 200px; margin-right: 20px"
          />
          <a-button style="width: 100px;margin-right: 20px" type="primary" @click="SearchInOrder">搜索
          </a-button>
          <a-space> {{ num ? indexNum + 1 : 0 }}/{{ num }}
            <UpOutlined @click="prev"/>
            <DownOutlined @click="next"/>
          </a-space>
          <div id="content" class="contentSearch">
    <div v-for="item in ContentList" class="contentSearchFor"
                 @mouseup="selectHandle">
              <h3 class="contentSearchH3">{{ item.title }}</h3>
              <div class="content" v-html="item.content"></div>
            </div>
//搜索锚点
async function SearchInOrder() {
  await SearchKeyword();
  getSearchNumber();
}

const num = ref(0)
const indexNum = ref(0)

// 关键字高亮
const SearchKeyword = () => {
  keyWordRed.value = true
  ContentList.value = dataSource.value
  if (searchValue.value && keyWordRed.value) {
    // 正则表达式规则,ig表示全局替换,区分大小写,key为输入的关键字
    const reg = new RegExp(`${searchValue.value}`, 'gi')
    // 用内容匹配关键字,如果有的话替换成带标签的内容给标签添加class类
    ContentList.value = ContentList.value.map((item) => {
        return {
          content: item.content.replace(reg, (val, index) => `<em class="searchValue" id="searchValue${index}"style='color:red;background-color: yellow'>${val}</em>`),
          title: item.title,
        }
      }
    )
  } else {
    keyWordRed.value = false
  }
}
// 全文锚点数量
const getSearchNumber = () => {
  num.value = document.getElementsByTagName("em").length
  indexNum.value = 0
}

// 上一个
const prev = () => {
  if (num.value !== 0) {
    for (let i = 0; i < document.getElementsByTagName('em').length; i++) {
      document.getElementsByTagName('em')[i].innerHTML = searchValue.value
    }
    if (indexNum.value === 0) {
      indexNum.value = num.value - 1
    } else {
      indexNum.value = indexNum.value - 1
    }
    document.getElementsByTagName('em')[indexNum.value].innerHTML =
      '<strong style="background-color: #ff9632">' +
      searchValue.value +
      '</strong>'
    document.getElementsByTagName('em')[indexNum.value].scrollIntoView()
  }
}
//下一个
const next = () => {
  if (num.value !== 0) {
    for (let i = 0; i < document.getElementsByTagName('em').length; i++) {
      document.getElementsByTagName('em')[i].innerHTML = searchValue.value
    }
    if (indexNum.value === num.value - 1) {
      indexNum.value = 0
    } else {
      indexNum.value = indexNum.value + 1
    }
    document.getElementsByTagName('em')[indexNum.value].innerHTML =
      '<strong style="background-color: #ff9632">' +
      searchValue.value +
      '</strong>'
    document.getElementsByTagName('em')[indexNum.value].scrollIntoView()
  }
}

这里有一个小问题,我懒得解决了,因为我是直接全文进行标签更改的,所以搜索数据中的index的数并不是0开始,懒得改了,可以改成另一种形式,大家自行改吧;

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值