【sgAutocomplete_v2】自定义组件:基于elementUI的el-input组件开发的搜索输入框(支持本地保存历史搜索关键词、后台获取匹配项)

特性:

  1. 支持本地记录搜索关键词
  2. 后台接口匹配搜索关键词
  3. 支持自定义填充字段名
  4. 支持user或address两种匹配列表布局样式

sgAutocomplete_v2 

<template><div :class="$options.name" @mouseover="inside = true" @mouseout="inside = false"><div class="search-layer"><el-inputclass="search-input"v-model.trim="inputSearchValue"maxlength="50":show-word-limit="false":placeholder="`你在找什么?快告诉我...`"clearable@keyup.native.enter="search"@focus="focusSearchInput"@clear="clearSearchInput"@input="inputingSearchInput"><el-button slot="append" icon="el-icon-search" @click="search"></el-button></el-input></div><div class="absolute-dropdownlist-layer" v-if="showAbsoluteDropdownlistLayer"><!-- 搜索建议 --><divclass="search-suggestion"v-if="historyKeywords.length > 0 && visible_search_suggestion"><!-- 搜索历史 --><div class="search-suggestion-item history"><div class="search-suggestion-item-head"><h1>最近搜索</h1><el-linkicon="el-icon-delete"type="danger":underline="false"@click.stop="clearAll">清除</el-link></div><ul class="historyKeywords"><li v-for="(a, i) in historyKeywords" :key="i"><el-tag:title="a"type="info"closable@click.stop="clickKeyword(a)"@close="closeTag(a)"><span class="text">{{ a }}</span></el-tag></li></ul></div></div><!-- 后台查询推荐匹配项 --><div class="matchList" v-if="matchList.length > 0"><ul><liv-for="(a, i) in matchList":key="i"@click.stop="clickMatchItem(a)":type="matchType"><template v-if="matchType == `user`"><div class="face"><img:src="a.src"v-if="a.src && !a.hideImg"@error="error($event, a, i)"/><el-avatarv-else:style="$g.convertData({ obj: `ROLE.PROFESSIONAL`, value: a.type }).style">{{a.username? a.username.slice(-1): a[matchKeyID] === "master"? "超": "未"}}</el-avatar></div><b class="username" v-html="a.username_HTML"> </b><span class="userid" v-html="a.userid_HTML"></span><spanclass="unit"v-html="`${a.unit_HTML ? `(${a.unit_HTML})` : ``}`"></span></template><template v-if="matchType == `address`"><b class="username" v-html="a.username_HTML"> </b><spanclass="address"v-html="`${a.address_HTML ? `[${a.address_HTML}]` : ``}`"></span></template></li></ul><div class="foot" v-if="showMoreBtn"><div class="more-btn" @click.stop="readmoreMatch" :loading="moreBtnLoading">{{ moreBtnLoading ? `加载中…` : `查看更多` }}</div></div></div></div></div>
</template>
<script>
export default {name: "sgAutocomplete_v2",components: {},data() {return {form: {},// ----------------------------------------inside: false, //鼠标是否在组件内showAbsoluteDropdownlistLayer: false, //显示absolute-dropdownlist-layerinputSearchValue: this.$route.query.keyword || "", //搜索关键词// 搜索建议----------------------------------------visible_search_suggestion: false, //显示搜索建议historyKeywords: [],// 搜索匹配----------------------------------------visible_search_match: false, //显示搜索匹配mainID: `ID`, //主键matchKeyID: `NAME`, //当点击匹配项,自动填充输入框的字段matchType: `user`, //默认匹配类型是user,枚举值:user、addressmatchList: [],keywordClassName: "match-autocomplete-keyword", //匹配高亮关键词样式showMoreBtn: false,moreBtnLoading: false,// ----------------------------------------};},props: ["value", "data"],computed: {},watch: {value: {handler(d) {this.inputSearchValue = d;},deep: true,immediate: true,},inputSearchValue(d) {this.$emit("input", d);},data: {handler(newValue, oldValue) {//console.log(`深度监听${this.$options.name}:`, newValue, oldValue);if (Object.keys(newValue || {}).length) {this.form = JSON.parse(JSON.stringify(newValue));this.form.matchType && (this.matchType = this.form.matchType);this.form.matchKeyID && (this.matchKeyID = this.form.matchKeyID);this.showMoreBtn = this.form.showMoreBtn;this.moreBtnLoading = this.form.moreBtnLoading;this.matchList = this.form.matchList || [];this.matchList = [...new Set(this.matchList.map((v) => v[this.matchKeyID])),].map((ID) => this.matchList.find((v) => v[this.matchKeyID] === ID)); //去重同样的ID数据this.setHighlightMatchList();this.$nextTick(() => {let matchListScrollDOM = this.$el.querySelector(`.matchList>ul`);matchListScrollDOM &&matchListScrollDOM.scrollTo({top: matchListScrollDOM.scrollHeight,behavior: "smooth",});});}},deep: true, //深度监听immediate: true, //立即执行},matchList: {handler(newValue, oldValue) {//console.log(`深度监听${this.$options.name}:`, newValue, oldValue);if (Object.keys(newValue || {}).length) {newValue.length > 0 && (this.visible_search_suggestion = false);}},deep: true, //深度监听immediate: true, //立即执行},},created() {this.initHistoryKeywords();},mounted() {this.__add();},destroyed() {this.__remove();},methods: {// 搜索输入框----------------------------------------search({ keyword = this.inputSearchValue } = {}) {this.visible_search_suggestion = false;this.saveHistoryKeywords();this.$emit(`search`, { keyword });},inputingSearchInput(keyword) {if (keyword === "") {this.visible_search_suggestion = true;}this.$emit(`change`, { keyword, isReset: true });},clearSearchInput(d) {this.visible_search_suggestion = true;},getmatchList({ matchList } = {}) {if (matchList.length > 0) {this.visible_search_suggestion = false;}},focusSearchInput(d) {this.showAbsoluteDropdownlistLayer = true;if (this.inputSearchValue.length === 0) {this.visible_search_suggestion = this.matchList.length === 0;} else {this.visible_search_suggestion = false;this.$emit(`change`, { keyword: this.inputSearchValue, isReset: true });}},saveHistoryKeywords(d) {let historyKeywords = (localStorage.historyKeywords || "").split("|");historyKeywords.unshift(this.inputSearchValue);historyKeywords = historyKeywords.filter(Boolean); //清空数组中的empty、undefined、nullhistoryKeywords = [...new Set(historyKeywords)];this.historyKeywords = historyKeywords;localStorage.historyKeywords = historyKeywords.join("|");},// 搜索建议----------------------------------------//初始化历史搜索记录initHistoryKeywords({ d } = {}) {this.historyKeywords = [...new Set((localStorage.historyKeywords || "").split("|").filter((v, i, ar) => v !== ``)),];},clickKeyword(d) {this.inputSearchValue = d;this.visible_search_suggestion = false;this.search();this.$nextTick(() => {this.focusSearchInput();});},closeTag(d) {this.historyKeywords = this.historyKeywords.filter((v, i, ar) => v !== d);localStorage.historyKeywords = this.historyKeywords.join("|");},clearAll(d) {this.visible_search_suggestion = false;this.historyKeywords = [];delete localStorage.historyKeywords;},// 搜索匹配----------------------------------------error($event, a, i) {this.$set(this.matchList[i], "hideImg", true);},clickMatchItem(a) {this.matchList = [];this.inputSearchValue = a[this.matchKeyID];this.search();},// 高亮匹配内容里面的关键词setHighlightMatchList() {let cls = this.keywordClassName;let keyword = this.inputSearchValue;this.matchList.forEach((d) => {Object.keys(d || {}).forEach((k) => {let originContent = this.$g.stripHTML(d[k]);d[`${k}_HTML`] = this.$g.highLightMatchString(originContent, keyword, cls);});});},readmoreMatch(d) {this.$emit(`readmoreMatch`, d);},// 全局监听----------------------------------------__add() {this.__remove();addEventListener("mousedown", this.__mousedown);},__remove() {removeEventListener("mousedown", this.__mousedown);},__mousedown(e) {this.inside || this.__hide(e); // 点击其他区域隐藏},__hide(e) {this.$emit("hide", e);this.showAbsoluteDropdownlistLayer = false;},__show(e) {this.$emit("show", e);this.showAbsoluteDropdownlistLayer = true;},},
};
</script>
<style lang="scss" scoped>
.sgAutocomplete_v2 {// 输入框搜索图层.search-layer {position: relative;z-index: 1;margin-bottom: 5px;.search-input {}}// 建议区域图层.absolute-dropdownlist-layer {z-index: 1;position: relative;width: 100%;$maxHeight: 400px; //下拉框最大高度// 搜索建议.search-suggestion {max-height: $maxHeight;position: absolute;top: 0;left: 0;box-shadow: 0 5px 20px 0 #00000022;background-color: white;border-radius: 4px;font-size: 14px;width: 100%;box-sizing: border-box;padding: 20px;.search-suggestion-item {margin-bottom: 20px;&:last-of-type {margin-bottom: 0;}.search-suggestion-item-head {display: flex;justify-content: space-between;align-items: center;margin-bottom: 20px;h1 {font-size: 14px;color: #2c343e;}}// 搜索历史.historyKeywords {display: flex;flex-wrap: wrap;margin-right: -10px;margin-bottom: -10px;max-height: calc(#{$maxHeight} - 80px);overflow-y: auto;li {margin-right: 10px;margin-bottom: 10px;>>> .el-tag {cursor: pointer;$tagMaxWidth: 200px;max-width: $tagMaxWidth;display: flex;align-items: center;&:hover,&:focus,&:active {border-color: #999;background-color: #00000009;span {color: black;}}.text {max-width: calc(#{$tagMaxWidth} - 20px);overflow: hidden;white-space: nowrap;text-overflow: ellipsis;display: inline-block;}.el-tag__close {flex-shrink: 0;}}}}}}// 搜索匹配.matchList {max-height: $maxHeight;position: absolute;top: 0;left: 0;box-shadow: 0 5px 20px 0 #00000022;background-color: white;border-radius: 8px;font-size: 14px;width: 100%;box-sizing: border-box;padding: 10px;ul {width: 100%;max-height: calc(#{$maxHeight} - 80px);overflow-y: auto;li {width: 100%;display: flex;align-items: center;box-sizing: border-box;padding: 10px;cursor: pointer;transition: 0.2s;border-radius: 8px;&[type="user"] {}&[type="address"] {}&:hover {filter: brightness(1.1);background-color: #00000009;}.face {margin-right: 10px;img,.el-avatar {width: 30px;height: 30px;display: flex;justify-content: center;align-items: center;object-position: center;object-fit: cover;border-radius: 88px;overflow: hidden;background-color: #00000009;}}.username {margin-right: 5px;color: black;}.userid {color: #999;margin-right: 10px;}.unit {color: #999;}.address {color: #999;}// 匹配高亮关键词样式>>> .match-autocomplete-keyword {color: #409eff;}}}.foot {box-sizing: border-box;display: flex;justify-content: center;align-items: center;.more-btn {padding: 10px;width: 100%;height: 100%;text-align: center;border-radius: 4px;cursor: pointer;transition: 0.2s;color: #409eff;&[loading] {pointer-events: none;}&:hover {background-color: #00000009;}}}}}
}
</style>

demo

<template><div :class="$options.name" style="display: flex; flex-wrap: nowrap"><sgAutocomplete_v2style="width: 500px":data="data_sgAutocomplete_v2"v-model="inputValue"@change="changeMatch"@readmoreMatch="readmoreMatch"@search="search"/><el-radio-groupv-model="data_sgAutocomplete_v2.matchType"size="small"style="margin-left: 10px; margin-top: 10px"><el-radiov-for="(radio, index) in radios":key="index":label="radio.value":disabled="radio.disabled">{{ radio.label }}</el-radio></el-radio-group></div>
</template>
<script>
import sgAutocomplete_v2 from "@/vue/components/admin/sgAutocomplete_v2";export default {name: "demoSgAutocomplete_v2",components: { sgAutocomplete_v2 },data() {return {radios: [{ value: `user`, label: "用户" },{ value: `address`, label: "地址" },],// ----------------------------------------inputValue: ``,data_sgAutocomplete_v2: {matchType: `user`, //默认匹配类型是user,枚举值:user、addressmatchKeyID: `NAME`, //当点击匹配项,自动填充输入框的字段matchList: [], //匹配项列表},// ----------------------------------------currentPage: 1,pageSize: 6,};},methods: {// 动态获取匹配项changeMatch({ keyword = this.inputValue, isReset } = {}) {if (!keyword) return (this.data_sgAutocomplete_v2.matchList = []);if (isReset) {this.data_sgAutocomplete_v2.matchList = [];this.currentPage = 1;}let data = {start: this.currentPage - 1, //当前页数(从0开始)limit: this.pageSize, //每页显示条目个数KEY: keyword, //匹配关键词};this.$f.biz_person_query({...data,l: {show: () => this.$set(this.data_sgAutocomplete_v2, "moreBtnLoading", true),close: () => this.$set(this.data_sgAutocomplete_v2, "moreBtnLoading", false),},cb: (d) => {//回调函数if (isReset) {this.data_sgAutocomplete_v2.matchList = []; //避免重复追加}let old_matchList = this.data_sgAutocomplete_v2.matchList;let matchList = old_matchList.concat(d.data || []);//转义适配字段matchList.forEach((v) => {v.type = v.TYPE;v.src = v.PHOTO_T ? this.$d.responseFile(v.PHOTO_T) : null; //头像路径v.username = v.NAME;v.userid = v.ACCOUNT;v.unit = v.UNIT_ID_TEXT;v.address = v.ADDRESS;});this.data_sgAutocomplete_v2.matchList = matchList;this.data_sgAutocomplete_v2.showMoreBtn = matchList.length < d.totalCount;},},this);},readmoreMatch(d) {this.currentPage++;this.changeMatch();},search(d) {// console.log(`搜索内容`, d, this.inputValue);},},
};
</script>

应用到了【全网最简短代码】去重对象数组中同一个ID的数据-CSDN博客【代码】【全网最简短代码】去重对象数组中同一个ID的数据。 https://blog.csdn.net/qq_37860634/article/details/146376768

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/37361.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法模型从入门到起飞系列——背包问题(探索最大价值的掘金之旅)

文章目录 前言一、背包问题溯源&#xff08;动态规划&#xff09;1.1 动态规划的概念1.2 动态规划的基本步骤1.3 动态规划的实际应用 二、背包问题2.1 背包问题衍生2.2 0-1背包2.2.1 0-1背包描述2.2.2 0-1背包图解2.2.3 0-1背包代码刨析 2.3 完全背包2.3.1 完全背包描述2.3.2 完…

数据库原理及应用mysql版陈业斌实验一

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 实验一&#xff1a;数据库与数据表的定义和数据操作 1.实验数据如下 …

腾讯云创建DeepSeek AI应用及使用教程

文章目录 腾讯云大模型知识引擎创建 DeepSeek 应用文档一、前期准备二、创建应用1. 进入应用管理界面2. 应用配置3. 发布应用 三、管理应用四、测试应用五、API接入应用API接入文档详细链接HTTP 对话端接口文档WebSocket对话端接口文档 六、常见问题七、注意事项 腾讯云大模型知…

关于FastAPI框架的面试题及答案解析

FastAPl是一个现代、快速(高性能)的Web框架,用于构建API,基于Python3.7+的类型提示功能。它由Python开发者SebastianRamirez创建,并且使用了Starlette作为其核心组件以及Pydantic进行数据验证。 文章目录 基础篇1. FastAPI的核心优势是什么?2. 如何定义一个GET请求路由?…

Linux上位机开发实战(camera视频读取)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 关于linux camera&#xff0c;一般都是认为是mipi camera&#xff0c;或者是usb camera。当然不管是哪一种&#xff0c;底层的逻辑都是v4l2&#x…

【强化学习】Reward Model(奖励模型)详细介绍

&#x1f4e2;本篇文章是博主强化学习&#xff08;RL&#xff09;领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅…

计算机组成原理和计算机网络常见单位分类及换算

计算机组成原理&#xff08;主要用于存储、内存、缓存等&#xff09; 计算机网络&#xff08;主要用于传输速率&#xff09; 直观对比

Elasticsearch零基础入门:从安装到入门

目录 一、Elasticsearch简介 二、环境快速搭建 1. 单节点本地部署&#xff08;Docker版&#xff09; 2. 验证安装 三、核心概念图解 与传统数据库对比 架构概念说明 四、REST API基础操作 1. 索引管理 2. 文档CRUD操作 五、基础搜索实战 1. 全文搜索 2. 精确匹配 …

数据清理工具——OpenRefine的进阶操作

第二章主要讲OpenRefine的进阶操作&#xff0c;希望能帮助你们&#xff01; 1.OpenRefine工具的数据排序功能 数据排序是一种常见的数据清理操作&#xff0c;它主要是按照指定方式排列数据&#xff0c;这样不仅可以对数据进行检查和纠错&#xff0c;还可以通过浏览排序后的数…

表格标题竖直

使用文本方式使表格怎么竖列 思路&#xff1a;表格竖直书写&#xff0c;里面的内容水平书写 使用到的是css中的文本效果&#xff1a; writing-mode&#xff1a;书写方式horizontal-tb&#xff1a;水平vertical-rl&#xff1a;竖直<style>table {writing-mode: vertical…

可视化图解算法:链表相加( 两数相加)

1. 题目 描述 假设链表中每一个节点的值都在 0 - 9 之间&#xff0c;那么链表整体就可以代表一个整数。 给定两个这种链表&#xff0c;请生成代表两个整数相加值的结果链表。 数据范围&#xff1a;0≤n,m≤10000000 &#xff0c;链表任意值 0≤val≤9 要求&#xff1a;空间…

YOLOv5

使用Yolov5 什么是PyTorch&#xff1f; PyTorch 是一个基于 Python 的开源机器学习库(深度学习框架)&#xff0c;它主要用于深度学习任务&#xff0c;为构建和训练神经网络提供了灵活且高效的平台&#xff0c;它们提供了完整的生态系统&#xff0c;包括模型定义、训练、验证…

【access开发】导入excel 并生成表

hi&#xff0c;大家好呀&#xff01; 最近天气越来越暖了&#xff0c;在这个春暖花开的季节了&#xff0c;每天心情应该都是美美的&#xff0c;正所谓一年之计在于春&#xff0c;在这个美好的季节&#xff0c;大家一起努力学习学习吧&#xff01;那我们来看看今天学点啥呢&…

查看GPU型号、大小;CPU型号、个数、核数、内存

GPU型号、大小 nvidia-smiCPU型号 cat /proc/cpuinfo | grep model name | uniqCPU个数 cat /proc/cpuinfo | grep "physical id" | uniq | wc -lCPU核数 cat /proc/cpuinfo | grep "cpu cores" | uniqCPU内存 cat /proc/meminfo | grep MemTotal参考…

如何使用AIOps明确Devps的问题归责

引言 拿出一个确凿的证据往往是解决背锅问题的重要办法。只有这样&#xff0c;才能够在没有互相指责、逃避责任或为自己及团队开脱等不良闹剧的情况下达成共识。DevOps 团队可以借助 AIOps 数据支持的可信度&#xff0c;让问题更清晰、背景更明确&#xff0c;从而一致做出更好…

Yolo系列之Yolo v3的概述、网络结构以及与v1,v2对比

Yolo v3的概述、模型理解以及与v1,v2对比 目录 Yolo v3的概述、模型理解以及与v1,v2对比1 YOLOv3概述1.1 概念1.2 主要特点1.3 优缺点 2 网络结构理解2.1 核心网络框架2.2 先验框2.3 特征图2.4 Softmax层替换 3 Yolo v3与v1,v2对比3.1 网络结构3.2 多尺度预测3.3 分类器与损失函…

AIGC工具平台-百叶窗卡点视频

本模块通过智能算法自动分析音频节奏&#xff0c;精准识别高潮卡点&#xff0c;并生成与音乐高度同步的动态视频。同时支持 百叶窗样式的个性化设置&#xff0c;增强视觉冲击力&#xff0c;助力用户打造节奏感强、富有创意的视频作品。 此外用户可灵活管理图片素材&#xff0c…

【原创】通过S3接口将海量文件索引导入elasticsearch

在医院海量影像文件通过s3传到蓝光存储时&#xff0c;要找一个文件需要全部文件遍历一遍&#xff0c;效率非常非常低。 S3 是对象存储服务&#xff0c;本身不是专门为快速文件查找设计的&#xff0c;而 Elasticsearch 是搜索引擎&#xff0c;在查找特定文件或数据方面具有明显…

MyBatis注解方式:从CRUD到数据映射的全面解析

目录 1. MyBatis是什么&#xff1f;2.准备工作2.1创建工程2.2 数据准备2.3 持久层代码2.4 单元测试 3.Mybatis的增删改查操作&#xff08;使用注解方式&#xff09;3.1 增&#xff08;insert&#xff09;3.2 删&#xff08;delete&#xff09;3.3 改&#xff08;update&#xf…

Java 大视界 -- 基于 Java 的大数据机器学习模型的多模态融合技术与应用(143)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…