vue3 codemirror插件setvalue后光标不跟随和光标显示错乱问题

816 阅读1分钟

大家好,我是前端小喵

WechatIMG18166.jpg

一、问题背景

在维护的codemirror插件实现的sql编辑器,新需求:用户进入页面,展示之前保存的sql;用了codemirror实例的setValue方法去实现了默认展示sql,但发现setValue后的编辑页面光标不跟随和光标显示错乱(如下截图)

image.png

二、关键代码

// 创建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组件的对象有代理,以便监控修改而刷新界面等,所以解决思路往去除响应式靠 image.png

四、解决办法

    // 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: {} // 代码提示
      }
    })
  )