大家好,我是前端小喵
一、问题背景
在维护的codemirror插件实现的sql编辑器,新需求:用户进入页面,展示之前保存的sql;用了codemirror实例的setValue方法去实现了默认展示sql,但发现setValue后的编辑页面光标不跟随和光标显示错乱(如下截图)
二、关键代码
// 创建CodeMirror 实例,sqlEditor.value保存
const codeOptions = {
lineNumbers: true,
lineWrapping: true,
styleActiveLine: true,
extraKeys: 'Ctrl',
theme: 'default'
}
const init = () => {
sqlEditor.value = CodeMirror.fromTextArea(codeMirrorRef.value, {
mode: 'text/x-sparksql', // spark sql模式
lineNumbers: codeOptions.lineNumbers, // 显示行号
styleActiveLine: codeOptions.styleActiveLine, // 激活当前行
theme: codeOptions.theme, // 主题
lineWrapping: codeOptions.lineWrapping, // 自动换行
matchBrackets: true, // 括号匹配
autoCloseBrackets: true,
line: true,
extraKeys: {
// 触发提示按键
[codeOptions.extraKeys]: 'autocomplete'
},
hintOptions: {
// 自定义提示选项
completeSingle: false, // 当匹配只有一项的时候是否自动补全
tables: {} // 代码提示
}
})
sqlEditor.value.setSize('auto', '360px')
editorEvents()
}
// 设置初始化sql
const setSql = val => {
sqlEditor.value.setValue(val)
}
三、分析问题
官网原话:有些值不应该是响应式的,例如复杂的第三方类实例;
vue对绑定到vue组件的对象有代理,以便监控修改而刷新界面等,所以解决思路往去除响应式靠
四、解决办法
// markRaw CodeMirror 实例
// 至于插件内部光标的实现思路暂未深入了解,优先解决问题先
sqlEditor.value = markRaw(
CodeMirror.fromTextArea(codeMirrorRef.value, {
mode: 'text/x-sparksql', // spark sql模式
lineNumbers: codeOptions.lineNumbers, // 显示行号
styleActiveLine: codeOptions.styleActiveLine, // 激活当前行
theme: codeOptions.theme, // 主题
lineWrapping: codeOptions.lineWrapping, // 自动换行
matchBrackets: true, // 括号匹配
autoCloseBrackets: true,
line: true,
extraKeys: {
// 触发提示按键
[codeOptions.extraKeys]: 'autocomplete'
},
hintOptions: {
// 自定义提示选项
completeSingle: false, // 当匹配只有一项的时候是否自动补全
tables: {} // 代码提示
}
})
)