<template> <div class="search-wrapper" :class="{ 'customer-bor': resultDisplay }"> <el-input prefix-icon="el-icon-search" placeholder="全局搜索" v-model="searchContent" :clearable="true" @keyup.enter.native="searchEvent" @keydown.up.native="preDownEvent" @keyup.up.native="preUpEvent" @keydown.down.native="nextDownEvent" @keyup.down.native="nextUpEvent" @focus="focusInput" @blur="blurInput" ></el-input> <div class="search-sug" v-show="resultDisplay" @mouseenter="isChoosing = true" @mouseleave="isChoosing = false" > <ul> <li :class="{ 'sug-selected': item.selected }" v-for="(item, idx) in searchResult" :key="idx" @mouseover="liOverEvent(idx)" @mouseup.left="searchEvent(item)" > <span style="width:8rem;display:inline-block">{{item.OWNREF}}</span> <el-divider direction="vertical"></el-divider> <span>{{item.OBJNAM}}</span> </li> </ul> </div> </div> </template> <script> import debounce from "lodash/debounce"; // import commonReport from "~/mixin/commonReport" export default { name: "SearchInput", mixins:[], data() { return { searchContent: "", searchResult: [], searchResultForLis: [], selectedIndex: 0, resultDisplay: false, // 鼠标选择结果集的状态 isChoosing: false, debounceWrapper: debounce(this.queryData, 500), }; }, watch: { searchContent: function(val, oldVal) { // console.log(val, oldVal); if (val.trim() === "") { this.searchResult = []; this.searchResultForLis = []; this.resultDisplay = false; return; } if (this.searchResult.map((r) => r.OWNREF).includes(val)) { return; } this.debounceWrapper(); }, }, methods: { async queryData() { // const testData = [ // { text: "DD3500210260AA01", url: "" }, // { text: "OC3500190001AA", url: "" }, // { text: "KZ3500210313AA", url: "" }, // { text: "KZ3500210312AA", url: "" }, // { text: "DD3500210311AA01", url: "" }, // { text: "DD3500210311AA01", url: "" }, // { text: "KZ3500210311AA", url: "" }, // { text: "CH3500200001AA", url: "" }, // { text: "CH3323200001AB", url: "" }, // { text: "DV453500210260AA01", url: "" }, // { text: "KZ3500210313AA", url: "" }, // { text: "DD45350029760AA01", url: "" }, // { text: "CH3500343657001AA", url: "" }, // { text: "CH35987567001AA", url: "" }, // { text: "CH243534200001AA", url: "" }, // { text: "CH350086786001AA", url: "" }, // { text: "CH53454001AA", url: "" }, // { text: "CH65645FG4545AA", url: "" }, // ]; console.log("query data ..." + new Date().toLocaleString()); let rtnmsg = await this.globalSearch(this.searchContent); if(rtnmsg.respCode == SUCCESS && rtnmsg.data && rtnmsg.data.length >0){ let srcData = rtnmsg.data; let searchResult = srcData.map(item=>{ return item; }) this.searchResult = searchResult; this.resultDisplay = true; } else{ this.searchResult = []; this.resultDisplay = false; } // this.shuffle(testData); // const res = testData; // const res = testData.filter( // (d) => d.text.indexOf(this.searchContent) > -1 // ); // if (res && res.length > 0) { // this.searchResultForLis = res.map((d) => { // const o = Object.assign({}, d); // o.text = d.text.replace( // this.searchContent, // "<em>" + this.searchContent + "</em>" // ); // return o; // }); // this.searchResult = res; // this.resultDisplay = true; // } else { // this.searchResult = []; // this.searchResultForLis = []; // this.resultDisplay = false; // } }, shuffle(arr) { let i = arr.length - 1; while (i > 0) { const n = (Math.random() * i) >>> 0; [arr[n], arr[i]] = [arr[i], arr[n]]; i--; } }, searchEvent(row) { if (typeof row.OWNREF === "string") { this.searchContent = row.OWNREF; } this.resultDisplay = false; // TODO let trns = { did:"ditsel", lid:"litsel", cpd:"cptsel", ded:"detsel", led:"letsel", bpd:"bptsel", ccd:"cctsel", ged:"getsel", gid:"gitsel", mcd:"mctsel", trd:"trtsel" } let objtyp = row.OBJTYP.trim().toLowerCase() let link = trns[objtyp]; console.log("go to ..."+link); if(!link){ this.$notify.error({title: '错误',message: '未知的objtyp:'+row.OBJTYP+"!"}) return } this.$router.push({name:link.toUpperCase().substring(0,1)+link.substring(1),query:{ownref:row.OWNREF.trim(),objtyp}}) }, focusInput() { if (this.searchResult.length > 0) { this.resultDisplay = true; } }, blurInput() { if (!this.isChoosing) { this.resultDisplay = false; } this.selectedIndex = -1; this.clearHighlightItem(); }, goNext() { if (this.searchResult.length === 0) { return; } if (this.selectedIndex >= this.searchResult.length - 1) { this.selectedIndex = 0; } else { this.selectedIndex++; } this.highlightItem(this.selectedIndex, true); }, goPre() { if (this.searchResult.length === 0) { return; } if (this.selectedIndex <= 0) { this.selectedIndex = this.searchResult.length - 1; } else { this.selectedIndex--; } this.highlightItem(this.selectedIndex, true); }, highlightItem(idx, changeVal) { // console.log(idx); const lis = this.$el.querySelectorAll(".search-sug ul li"); lis.forEach((li) => (li.className = "")); if (lis[idx] && this.searchResult[idx]) { lis[idx].className = "sug-selected"; if (changeVal) { this.searchContent = this.searchResult[idx].text; } } }, liOverEvent(idx) { this.selectedIndex = idx; this.highlightItem(idx, false); }, clearHighlightItem() { this.$el .querySelectorAll(".search-sug ul li") .forEach((li) => (li.className = "")); }, /** * up按下 */ preDownEvent() { // console.log("up key: down"); this.goPre(); }, /** * up弹起 */ preUpEvent() { // console.log("up key: up"); }, /** * down按下 */ nextDownEvent() { // console.log("down key: down"); this.goNext(); }, /** * down弹起 */ nextUpEvent() { // console.log("down key: up"); }, }, }; </script> <style scoped> .search-wrapper { position: relative; } .search-wrapper >>> .el-input { z-index: 101; /* position:absolute; */ } .search-wrapper >>> .el-input input::-ms-input-placeholder{text-align: center;} .search-wrapper >>> .el-input input::-webkit-input-placeholder{text-align: center;} .search-wrapper >>> .el-input .el-input__inner { padding: 10px 20px 10px 30px; } .search-sug { position: absolute; width: 590px; top: 28px; height: 40rem; overflow: auto; border-radius: 0 0 10px 10px; border: 2px solid #4e71f2; box-shadow: none; font-family: "Microsoft YaHei", Arial, sans-serif; z-index: 100; background: #fff; } .search-sug ul { margin: 7px 14px 0; padding: 8px 0 7px; background: 0 0; border-top: 2px solid #f5f5f6; } .search-sug ul li { list-style: none; width: auto; padding: 0 8px; padding-left: 14px; margin-left: -14px; margin-right: -14px; color: #626675; font: 14px arial; line-height: 28px; background: 0 0; font-family: "Microsoft YaHei", Arial, sans-serif; position: relative; cursor: pointer; } .search-sug ul li.sug-selected { background-color: #f5f5f6; color: #315efb; } .search-wrapper >>> .el-input__inner:focus { border: 2px solid #4e71f2; outline: 0; } .customer-bor >>> .el-input__inner { border-bottom: 0 !important; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .search-sug ul li >>> em { color: #f73131; font-style: normal; } </style>