赞
踩
自定义sql编辑器的提示信息,原来只提示匹配到的结果内容,现在需要增加匹配到的类型展示,比如输入t,则提示tid column,table1 table,timestamp() function,TABLES keyword等。
项目主要参考vue-codemirror,使用组件codemirror实现,修改了codemirror中的sql-hint.js和show-hint.js文件。
1、将node modules文件夹下codemirror中部分源码包括addon,keymap,lib,mode,theme拷贝至自己的组件代码中,创建code-mirror.vue及index.js文件。其中,index.js主要用于导出及实现install方法,不做详细介绍。code-mirror.vue参考vue-codemirror中对应代码,主要包括引入对应文件,定义事件以及初始化编辑器,注意:此处引入的是我们拷贝到本地的文件,这样就可以使用修改后的代码。
2、修改sql-hint.js。sql-hint.js主要修改wrapTable、addMatches函数。
项目需要支持传入的hintOptions格式为{completeSingle:false,tables:{source1:{array:[table1,table2],type:‘source’},timestamp:{array:[],type:‘function’}},或者是{completeSingle:false,tables:{source1:{array:[{text:‘table1’,type:‘table’},{text:‘table2’,type:‘table’}],type:‘source’},timestamp:{array:[],type:‘function’}}
parseTables函数将传入的tables解析成固定的格式,主要使用的函数是wrapTable,这个函数需要修改部分代码,因为我们传入的数据类型变了;且需要对传入的第一种array数据不包含type的数据格式进行处理。
function wrapTable(name, value) { if (isArray(value.array)) { let childrenArr = [] if (value.type === 'source') { childrenArr = value.array.map(item => { if (typeof item === 'object') { return item } else { return { text: item, type: 'table' } } }) } else if (value.type === 'table') { childrenArr = value.array.map(item => { if (typeof item === 'object') { return item } else { return { text: item, type: 'column' } } }) } value = { columns: childrenArr, type: value.type } } if (!value.text) value.text = name return value }
在addMatches函数中,需要将result修改为既包含value又包含类型的格式。
function addMatches(result, search, wordlist, fomatter) { if (isArray(wordlist)) { for (var i = 0; i < wordlist.length; i++) { var type = wordlist[i].type || '' //如果需要控制提示信息个数可在此处处理 if (match(search, wordlist[i])) { let res = fomatter(wordlist[i]) if (typeof res === 'string') { result.push({ text: res, type }) } else { result.push({ ...res, type }) } } } } else { for (var word in wordlist) { if (wordlist.hasOwnProperty(word)) { var val = wordlist[word] var type = val.type || '' if (!val || val === true) { val = word } else { val = val.displayText ? { text: val.text, displayText: val.displayText } : val.text } //如果需要控制提示信息个数可在此处处理 if (match(search, wordlist[i])) { let res = fomatter(wordlist[i]) if (typeof res === 'string') { result.push({ text: res, type }) } else { result.push({ ...res, type }) } } } } } }
3、show-hint函数修改。主要修改展示部分,之前只展示提示词,目前需要增加类型的展示。主要修改Widget函数
function Widget(completion, data) { //上面代码不做修改 var completions = data.list; for (var i = 0; i < completions.length; ++i) { var elt = hints.appendChild(ownerDocument.createElement("li")), cur = completions[i]; var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); if (cur.className != null) className = cur.className + " " + className; elt.className = className; //源码修改部分 var span = document.createElement('SPAN') span.style.color = 'white' span.style.cssFloat = 'right' let text = " " + (cur.type ? cur.type : 'keyword') var type = document.createTextNode(text); span.appendChild(type) if (cur.render) { cur.render(elt, data, cur) } else { elt.append(ownerDocument.createTextNode(cur.displayText || getText(cur)), span) } elt.hintId = i; } //后面其他代码不做修改 return true; } 在这里插入代码片
需要注意的是,由于直接从node modules中拷贝过来的文件是经过umd方式打包过的,直接引入由于模块类型问题导致无法使用,应将引入的js文件修改为es6的模块化方式。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。