当前位置: 首页 > news >正文

< vue + ElementUi 组件封装:实现弹窗展示富文本数据,允许全文搜索高亮显示搜索内容 >

在这里插入图片描述

实现弹窗展示富文本数据,允许全文搜索高亮显示搜索内容

  • 👉 前言
  • 👉 一、效果演示
  • 👉 二、实现思路
  • 👉 三、实现案例
  • 👍 卷王必胜!
  • 往期内容 💨


👉 前言

在 Vue + elementUi 开发中,遇到需要实现一个富文本展示 且 需要实现富文本全文搜索,高亮对应搜索内容。显示关键词出现次数,允许上下按顺序切换,实现滚动条定位到对应关键词位置!

接下来,简单阐述下,开发中使用方法!


👉 一、效果演示

话不多说,先上效果图! 白嫖万岁!当然,如果有帮助,希望不要吝啬你的点赞呀!

效果图
效果图二

以上数据来源于互联网记载的国内法律法规条例文献!

👉 二、实现思路

通过 v-html 将富文本解析到页面指定位置展示,并且预设的 class名称,通过 document.querySelectorAll() 查询已渲染到页面的内容。

通过正则 htmlContent.replace(new RegExp(this.keyword, 'g'), 替换内容)。替换内容,通常为html样式的keyword)

其实不难发现,在vueJavaScript 中进行全文搜索有些许不同。由于其中搜索的HTML是我们通过 v-html渲染 到页面上,它享有Vue数据双向绑定的特性,我们其实只需要对v-html绑定的变量参数进行修改,即可实时渲染到页面。当然有些标签属性变更,使用JavaScript来修改可能会更加高效一点。

稍微增加一点切换的滚动条挪动 及 样式清除细节逻辑!直接看代码吧! 简单易懂!

👉 三、实现案例

> 父组件中引用

<template>
<fullTextSearchDialogv-if="lawDialogVisible"ref="fullTextSearchDialog":curTitle="curTitle":content="lawFullText"@close="closeLawFullTextDialog"
/>
</template><script>
import fullTextSearchDialog from "@/views/components/dialog/fullTextSearchDialog.vue";data() {return {lawDialogVisible: false,curTitle: '',lawFullText: '',}
}
methods: {// 打开法律法规全文openLawFullTextDialog(item) {this.curTitle = item.title;this.lawFullText = item.fullText;this.lawDialogVisible = truesetTimeout(() => {this.$refs.fullTextSearchDialog.openDialog()}, 0)},// 关闭全文弹窗closeLawFullTextDialog() {this.curTitle = '';this.lawFullText = ''this.lawDialogVisible = false},
}
</script>

> 子组件模板

<template><el-dialog:title="curTitle + '-全文'":visible.sync="lawDialogVisible"width="61.7%"height="500":close-on-click-modal="true":modal="false"custom-class="abolishDialog"@close="handleClose"><div class="lawContent"><div class="searchBox">全文内容搜索:<el-inputplaceholder="请输入关键词"v-model="keyword"class="input-with-select":clearable="false"style="width: calc(100% - 240px);"><div class="indexChange" slot="suffix"><span class="index">{{ searchIndex + ' / ' + searchAllIndexs }}</span><div class="btnBox"><i class="el-icon-arrow-up" @click="searchIndexDown"></i><i class="el-icon-arrow-down" @click="searchIndexUp"></i></div></div></el-input><el-button type="primary" size="mini" @click="lawFullTextSearch">查 询</el-button><el-button size="mini" @click="resetSearch(true)">重 置</el-button></div><div class="fullTextContent"><pv-if="refresh"style="width: 100%;"v-html="lawFullText || '暂无数据'"class="el-tiptap-editor__content"></p></div></div></el-dialog>
</template><script>
export default {components: {},props: {curTitle: {type: String,default: () => {return '提示';},},content: {type: String,default: () => {return '';},},},data() {return {lawDialogVisible: false, //弹框显隐lawFullText: '',searchIndex: 0,searchAllIndexs: 0,keyword: '',refresh: true,};},mounted() {this.lawFullText = JSON.parse(JSON.stringify(this.content))},watch: {},computed: {},methods: {/*** @description:打开弹框回调*/openDialog() {this.lawDialogVisible = true;},// 法律法规全文内容关键词搜索高亮lawFullTextSearch() {// window.console.log(this.keyword)if (this.keyword && this.keyword !== '' && this.lawFullText.indexOf(this.keyword) != -1) {this.searchAllIndexs = (this.lawFullText.split(this.keyword).length - 1) || 0this.searchIndex = 1this.lawFullText = this.lawFullText.replace(new RegExp(this.keyword, 'g'), `<em class='searchText'>${this.keyword}</em>`); // 通过正则全局匹配关键字,查出来的文字进行高亮替换setTimeout(() => {let allSearchIndex = document.querySelectorAll('em')allSearchIndex[this.searchIndex - 1].className = 'curSearchText'// 使滚动条滚动到指定位置this.scrollChange()}, 0)} else {this.resetSearch()this.$message.info('无当前查询内容 或 未输入关键词!')}},// 重置搜索内容resetSearch(resetKey = false) {if(resetKey) {this.keyword = ''}this.searchAllIndexs = 0;this.searchIndex = 0;// 清除上次的查询记录this.lawFullText = this.lawFullText.replace(new RegExp('</?em.*?>', 'gi'), ``);// 刷新this.refresh = false;setTimeout(() => {this.refresh = true;}, 0)},// 查询内容上一个searchIndexUp() {if(this.searchIndex > 0 && this.searchIndex <= this.searchAllIndexs && this.searchAllIndexs > 0) {this.searchIndex = (this.searchIndex + 1) > this.searchAllIndexs ? 1 : (this.searchIndex + 1)setTimeout(() => {let allSearchIndex = document.querySelectorAll('em')// 清除上一个选中样式allSearchIndex[this.searchIndex - 2 < 0 ? this.searchAllIndexs - this.searchIndex : this.searchIndex - 2].className = 'searchText'allSearchIndex[this.searchIndex - 1].className = 'curSearchText'// 使滚动条滚动到指定位置this.scrollChange()}, 0)} else {this.searchIndex = 0}},// 查询内容下一个searchIndexDown() {if(this.searchIndex > 0 && this.searchIndex <= this.searchAllIndexs && this.searchAllIndexs > 0) {this.searchIndex = (this.searchIndex - 1) <= 0 ? this.searchAllIndexs : (this.searchIndex - 1)setTimeout(() => {let allSearchIndex = document.querySelectorAll('em')// 清除上一个选中样式allSearchIndex[this.searchIndex > this.searchAllIndexs - 1 ? this.searchAllIndexs - this.searchIndex  : this.searchIndex].className = 'searchText'allSearchIndex[this.searchIndex - 1].className = 'curSearchText'// 使滚动条滚动到指定位置this.scrollChange()}, 0)} else {this.searchIndex = 0}},/*** @description:关闭弹框回调*/handleClose() {this.lawDialogVisible = false;setTimeout(() => {this.lawFullText = ''this.keyword = ''this.searchIndex = 0this.searchAllIndexs = 0this.$emit('close')}, 0)},// 滚动条定位scrollChange() {let fullTextDom = document.querySelector('.fullTextContent')let curDom = document.querySelector('.curSearchText').parentNode// window.console.log(curDom, curDom.offsetTop)fullTextDom.scrollTop = curDom.offsetTop - 137  || 0},},
};
</script><style lang="scss" scoped>
/deep/ {.abolishDialog {background: #ffffff !important;border: 1px solid #cccccc !important;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);border-radius: 4px;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);margin-top: 0 !important;min-width: 480px;.lawContent {height: 50vh;min-height: 500px;display: flex;align-content: space-around;flex-wrap: wrap;.searchBox {width: 100%;display: flex;justify-content: space-around;align-items: center;.el-input__inner {padding-right: 100px;}.el-input__suffix-inner {width: 90px;display: flex;justify-content: space-between;.indexChange {width: 100%;display: flex;justify-content: space-around;align-items: center;.btnBox {display: flex;flex-direction: column;margin: 0 5px;}}}}.fullTextContent {width: 100%;height: calc(100% - 70px);padding-top: 20px;overflow-y: auto;.searchText {background-color: yellow;color: #333;font-weight: bold;margin: 0 3px;padding: 2px;border-radius: 5px;}.curSearchText {background-color: red;color:white;padding: 3px;font-weight: bold;margin: 0 3px;padding: 2px;border-radius: 5px;}}}.el-dialog__header {border-bottom: 0.5px solid #cccccc !important;padding: 0 15px;font-weight: bold;display: flex;align-items: center;justify-content: space-between;.el-dialog__headerbtn {width: 20px;position: relative;top: 0;right: 0;}// height: 48px !important;}.el-dialog__body {// min-height: 100px;padding: 15px;.title {font-size: 10.5px;color: #f56c6c;text-align: right;margin-top: 15px;}}.el-dialog__footer {border-top: 0.5px solid #cccccc !important;padding: 10px;}}
}
</style>

案例较为粗浅,仅供参考!

👍 卷王必胜!

如果本篇文章对您有所帮助! 请不要吝惜您的小手,给小温来个小小的点赞!您的支持是对小温无比的认同!


往期内容 💨

🔥 < 每日算法:一文带你认识 “ 双指针算法 ” >

🔥 < 每日小技巧: 基于Vue状态的过渡动画 - Transition 和 TransitionGroup>

🔥 < JavaScript技术分享: 大文件切片上传 及 断点续传思路 >

🔥 < 每日份知识快餐:axios是什么?如何在Vue中 封装 axios ? >

🔥 < 面试知识点:什么是 Node.js ?有哪些优缺点?应用场景? >

相关文章:

< vue + ElementUi 组件封装:实现弹窗展示富文本数据,允许全文搜索高亮显示搜索内容 >

实现弹窗展示富文本数据&#xff0c;允许全文搜索高亮显示搜索内容 &#x1f449; 前言&#x1f449; 一、效果演示&#x1f449; 二、实现思路&#x1f449; 三、实现案例&#x1f44d; 卷王必胜&#xff01;往期内容 &#x1f4a8; &#x1f449; 前言 在 Vue elementUi 开…...

MATLAB 之 低层绘图操作和光照及材质处理

这里写目录标题 一、低层绘图操作1. 曲线对象2. 曲面对象3. 文本对象4. 其他核心对象4.1 区域块对象4.2 方框对象 二、光照和材质处理1. 光照处理2. 材质处理2.1 图形对象的反射特性2.2 material 函数 一、低层绘图操作 MATLAB 将曲线、曲面、文本等图形均视为对象&#xff0c…...

LLM-Client一个轻量级的LLM集成工具

大型语言模型(llm)已经彻底改变了我们与文本交互的方式&#xff0c;OpenAI、Google、AI21、HuggingfaceHub、Anthropic和众多开源模型提供了不同的功能和优势。但是每个模型都有其独特的体系结构、api和兼容性需求&#xff0c;集成这些模型是一项耗时且具有挑战性的任务。 所以…...

leetcode动态数组vector实现杨辉三角

链接: leetcode动态数组vector实现杨辉三角 由题意可易得&#xff0c;从第三行开始&#xff0c;除了开始和末尾的位置上的元素&#xff0c;其余位置上的元素都是由上方的元素以及上方左侧的元素相加得到的&#xff0c;此时就很容易的到从第三行开始状态转移方程为vv[i][j] vv[…...

第二十三章_Redis高性能设计之epoll和IO多路复用深度解析

before 多路复用要解决的问题 并发多客户端连接&#xff0c;在多路复用之前最简单和典型的方案&#xff1a;同步阻塞网络IO模型 这种模式的特点就是用一个进程来处理一个网络连接(一个用户请求)&#xff0c;比如一段典型的示例代码如下。 直接调用 recv 函数从一个 socket 上读…...

基于OpenCV-车辆检测项目(简易版)

车辆检测 1.项目介绍2. 读取一段视频3.通过形态学处理识别车辆4.描画轮廓5. 车辆计数并显示 本项目使用的视频地址链接 1.项目介绍 对一个视频进行车辆数量的检测&#xff0c;用到的知识有视频的读取&#xff0c;滤波器&#xff0c;形态学&#xff0c;添加直线、文本&#xff…...

用python获取海康摄像机视频

要调用海康摄像机视频&#xff0c;需要使用海康SDK提供的API。以下是一个简单的示例代码&#xff0c;可以连接到海康摄像机并获取视频流&#xff1a; python import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel from PyQt5.QtGui import QPixmap from PyQ…...

【Linux】遇事不决,可先点灯,LED驱动的进化之路---2

【Linux】遇事不决&#xff0c;可先点灯&#xff0c;LED驱动的进化之路---2 前言&#xff1a; 一、Pinctrl子系统重要概念 1.1 重要概念 1.1.1 pin controller 1.1.2 client device 1.1.3 补充概念 二、GPIO子系统重要概念 2.1 在设备树指定GPIO引脚 2.2 在驱动代码中…...

【计算机网络】数据链路层--点对点协议PPP

1.概念 2.构成 3.封装成帧 - 帧格式 4.透明传输 4.1字节填充法&#xff08;面向字节的异步链路&#xff09; 4.2.比特填充法&#xff08;面向比特的同步链路&#xff09; 5.差错检测 6.工作状态 7.小结...

【⑦MySQL】· 一文了解四大子查询

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL标量/单行子查询、列子/表子查询的讲解✨ 目录 前言一、子查询概念二、标量/单行子查询、列子/表子查询三、总结 一、子查询概念 子查询指一个查询语句嵌套在另一个查询语句内部的查询&#xff0c;这个特性从My…...

ValSuite报告可以帮助改善您的验证过程的6种方式

热验证工艺是一项复杂而微妙的工作&#xff0c;但它是确保制药和生物技术产品的安全性和有效性的重要组成部分。同时&#xff0c;管理整个验证过程中产生的数据可能很费时&#xff0c;而且容易出错——这就是ValSuite的意义。 这款直观的验证软件简化了数据分析和报告&#xf…...

【机器学习】机器故障的二元分类模型-Kaggle竞赛

竞赛介绍 数据集描述 本次竞赛的数据集&#xff08;训练和测试&#xff09;是从根据机器故障预测训练的深度学习模型生成的。特征分布与原始分布接近&#xff0c;但不完全相同。随意使用原始数据集作为本次竞赛的一部分&#xff0c;既可以探索差异&#xff0c;也可以了解在训…...

ADB usage

查看手机设备的信息 获取设备的Android版本号 adb shell getprop ro.build.version.release 获取设备的API版本号 adb shell getprop ro.build.version.sdkAdb 获得 sdk版本 adb shell getprop ro.build.version.sdk27 Adb 获得Android版本 adb shell getprop ro.build.vers…...

利用有限元法(FEM)模拟并通过机器学习进行预测以揭示增材制造过程中热场变化:基于ABAQUS和Python的研究实践

1. 引言 增材制造&#xff08;Additive Manufacturing&#xff0c;AM&#xff09;近年来引起了大量的研究关注&#xff0c;这主要是因为它可以提供定制化、复杂结构的零件制造解决方案。在AM过程中&#xff0c;热场的分布和变化直接影响了零件的质量和性能。对此&#xff0c;采…...

Kafka与Flume的对比分析

Kafka与Flume的对比分析 一、Kafka和Flume1. Kafka架构2. Flume架构3. Kafka和Flume异同点 二、Kafka和Flume的性能对比1. 数据处理性能对比2. 大规模数据流处理的性能对比 三、性和稳定性对比1. 高可用集群的搭建KafkaFlume 2. 数据丢失和重复消费的问题处理KafkaFlume 四、适…...

docker启动redis哨兵报错(sentinel.conf is not writable: Permission denied)

Sentinel config file /usr/local/sentinel/sentinel.conf is not writable: Permission denied. Exiting… 用这个命令不报错&#xff1a;docker run --net host -p 6666:6666–name redis-sentinel -v /usr/mcc/redis/conf:/usr/local/sentinel/ -v /usr/mcc/redis/data/sent…...

如何编写优秀代码

最近在阅读别人写的代码&#xff0c;进行相应功能的修改。发现很多不规范或者比较绕的地方&#xff0c;总有那么几句看着多此一举&#xff0c;阅读别人的代码就是这样&#xff0c;有时候真的不懂写代码的人当时怎么想的。 例如有这么一段&#xff1a; 用户输入一个名字&#…...

信道编码:Matlab RS编码、译码使用方法

Matlab RS编码、译码使用方法 1. 相关函数 在MATLAB中进行RS编码的过程可以使用rsenc()函数或者comm.RSEncoder()函数。 1.1 rsenc()函数使用方法 在MATLAB中帮助中可以看到有三种使用形式&#xff0c;分别为 code rsenc(msg,n,k) code rsenc(msg,n,k,genpoly) code rs…...

数据结构第六章 图 6.1-6.3 错题整理

6.1 6.C 加上一个点实现非连通 去除每个边都是一颗不同的生成树 一共n条边 13.C n个顶点、e条边的无向图&#xff0c;森林。树的角度看&#xff0c;除了根节点没有一条边与其对应&#xff0c;其他顶点都对应一条边&#xff0c;用顶点-边得出有多少颗树 14.A II 等于 也可以…...

12 MFC常用控件(一)

文章目录 button 按钮设置默认按钮按下回车后会响应禁用开启禁用设置隐藏设置显示设置图片设置Icon设置光标 Cbutton 类创建按钮创建消息单选按钮多选按钮 编辑框组合框下拉框操作 CListBox插入数据获取当前选中 CListCtrl插入数据设置表头修改删除 button 按钮 设置默认按钮按…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...