vue+element-ui实现搜索文字并高亮定位显示

首先看一下效果,定位到画布上的节点
在这里插入图片描述
先上代码
代码模块1

// 搜索框html代码
<el-input
	placeholder="请输入节点名称"
	prefix-icon="el-icon-search"
	v-model="searchNodeInput"
	@input="changeSearchNodeInput"
	@keyup.down.native="inputDown"
	@keyup.up.native="inputUp"
	@keyup.enter.native="inputDown"
	clearable
	>
	<template slot="append">
	  <div class="searchRight">
	    <span class="item">{{nowNum}}/{{totalNum}}</span>
	    <el-tooltip class="item" effect="dark" content="上一个" placement="top">
	      <el-button @click="inputUp" :disabled="inputUpDisable" icon="el-icon-arrow-up" circle type="text"></el-button>
	    </el-tooltip>
	    <el-tooltip class="item" effect="dark" content="下一个" placement="top">
	      <el-button @click="inputDown" :disabled="inputDownDisable" icon="el-icon-arrow-down" circle type="text"></el-button>
	    </el-tooltip>
	  </div>
	</template>
</el-input>

其中涉及到的@keyup事件
在这里插入图片描述
代码模块2

// 上一个
    inputUp () {
      if (this.totalNum >= 1) {
        this.inputUpDisable = false
        if (this.currentNodeIndex === 0) {
          this.currentNodeIndex = Number(this.totalNum) - 1
          this.nowNum = String(this.currentNodeIndex + 1)
          this.currentLabel = this.nodeSearchArr[this.currentNodeIndex].label
        } else {
          this.currentNodeIndex = this.currentNodeIndex - 1
          this.nowNum = String(this.currentNodeIndex + 1)
          this.currentLabel = this.nodeSearchArr[this.currentNodeIndex].label
        }
      } else {
        // 这里向上的按钮要disable掉
        this.inputUpDisable = true
      }
    },
    // 下一个
    inputDown () {
      if (this.totalNum >= 1) {
        this.inputDownDisable = false
        if (this.currentNodeIndex === this.totalNum - 1) {
          this.currentNodeIndex = 0
          this.nowNum = String(this.currentNodeIndex + 1)
          this.currentLabel = this.nodeSearchArr[this.currentNodeIndex].label
        } else {
          this.currentNodeIndex = this.currentNodeIndex + 1
          this.nowNum = String(this.currentNodeIndex + 1)
          this.currentLabel = this.nodeSearchArr[this.currentNodeIndex].label
        }
      } else {
        // 这里向下的按钮要disable掉
        this.inputDownDisable = true
      }
    },
    // 改变搜索框中的值
    changeSearchNodeInput (value) {
      const Reg = new RegExp(value, 'i')
      const arr = []
      for (const i of this.nodesData.nodeList) {
        if (i.label.search(Reg) !== -1) {
          arr.push(i)
        }
      }
      this.nodeSearchArr = arr
      this.totalNum = arr.length
      if (this.totalNum >= 1) {
        this.nowNum = '1'
        this.currentLabel = arr[0].label
        this.currentNodeIndex = 0
        this.inputUpDisable = false
        this.inputDownDisable = false
      } else {
        this.nowNum = '0'
        this.inputUpDisable = true
        this.inputDownDisable = true
      }
    },

然后在画布上的节点上需要

代码模块3

<div
   v-html="brightenKeyword(node.label, searchNodeInput)"
   class="node-label-failure"
 >
   {{ node.label }}
 </div>

代码模块4

	// node节点搜索高亮
    brightenKeyword(val, keyword) {
      // 方法1:筛选变色(区分大小写)
      // val = val + '';
      // if (val.indexOf(keyword) !== -1 && keyword !== '') {
      //   if (val === this.currentNodeLabel) {
      //     const resCurrent = val.replace(keyword, `<span style="color: #000;background-color: orange;">${keyword}</span>`)
      //     return resCurrent
      //   } else {
      //     const res = val.replace(keyword, `<span style="color: #000;background-color: yellow;">${keyword}</span>`)
      //     return res
      //   }
      // } else {
      //   return val
      // }
      // 方法2:用正则表达式 (不区分大小写)
      const Reg = new RegExp(keyword, 'i')
      if (val) {
        if (val === this.currentNodeLabel) {
          // 这里为什么使用$&不使用keyword,因为这里使用正则表达式不区分大小写,如果是文本时大写,搜索的关键字是小写也是会被匹配的,这样匹配替换掉的话,文本内的文字会被替换成搜索的keyword,也就是改成了小写,这样不太合理
          // const resCurrent = val.replace(Reg, `<span style="color: #000;background-color: orange;">${keyword}</span>`)
          const resCurrent = val.replace(Reg, `<span style="color: #000;background-color: orange;">$&</span>`)
          return resCurrent
        } else {
          const res = val.replace(Reg, `<span style="color: #000;background-color: yellow;">$&</span>`)
          return res
        }
      }
    },

代码中的currentNodeLabel是从父节点传过来的,因为开发过程中节点是单独抽离的组件,然后这里的val === this.currentNodeLabel是为了判断当前定位的是哪一个node节点,进行不同的高亮与定位。

我的操作流程是先用“代码模块1”和“代码模块3和4”实现的高亮,这个很简单,但是后面需要定位到当前的节点,并且可以上下翻动,因此增加了代码模块2也修改了一点代码模块1和4

主要参考了这两篇文章实现
1、https://blog.csdn.net/qq_35366269/article/details/94390643 vue中的keyup事件
2、https://blog.csdn.net/weixin_43961899/article/details/100580629 这篇参考了通过按键触发节点定位
3、https://blog.csdn.net/qq_38543537/article/details/96426047 搜索及高亮参考这篇文章

还有一些知识需要查看JS相关的知识
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值