服务器之家

服务器之家 > 正文

vue 使用monaco实现代码高亮

时间:2022-02-12 18:17     来源/作者:lgx211

使用的是vue语言,用element的组件,要做一个在线编辑代码,要求输入代码内容,可以进行高亮展示,可以切换各不同语言,而且支持关键字补全,还要有一个各不同版本间的代码左右比较,这就是需求。

至于为什么选中monaco,请查看 vue(element)中代码高亮插件全面对比

好了,现在正式开工吧!

首先需要下载monaco-editor组件,monaco-editor-webpack-plugin组件

npm install monaco-editor
npm install monaco-editor-webpack-plugin

当然啦,npm下载很是缓慢,换个国内镜像,淘宝的吧。果然,速度就嗖嗖的起来。

npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install

cnpm install monaco-editor
cnpm install monaco-editor-webpack-plugin

可在node_modules下看到其目录结构

vue 使用monaco实现代码高亮

核心代码如下所示

首先写个组件,供其他页面引入调用,

CodeEditor.vue

<template>
 <div class="code-container" ref="container"></div>
</template>

<script>
 import * as monaco from "monaco-editor";
 let sqlStr =
 "ADD EXCEPT PERCENT ALL EXEC PLAN ALTER EXECUTE PRECISION AND EXISTS PRIMARY ANY EXIT PRINT AS FETCH PROC ASC FILE PROCEDURE AUTHORIZATION FILLFACTOR PUBLIC BACKUP FOR RAISERROR BEGIN FOREIGN READ BETWEEN FREETEXT READTEXT BREAK FREETEXTTABLE RECONFIGURE BROWSE FROM REFERENCES BULK FULL REPLICATION BY FUNCTION RESTORE CASCADE GOTO RESTRICT CASE GRANT RETURN CHECK GROUP REVOKE CHECKPOINT HAVING RIGHT CLOSE HOLDLOCK ROLLBACK CLUSTERED IDENTITY ROWCOUNT COALESCE IDENTITY_INSERT ROWGUIDCOL COLLATE IDENTITYCOL RULE COLUMN IF SAVE COMMIT IN SCHEMA COMPUTE INDEX SELECT CONSTRAINT INNER SESSION_USER CONTAINS INSERT SET CONTAINSTABLE INTERSECT SETUSER CONTINUE INTO SHUTDOWN CONVERT IS SOME CREATE JOIN STATISTICS CROSS KEY SYSTEM_USER CURRENT KILL TABLE CURRENT_DATE LEFT TEXTSIZE CURRENT_TIME LIKE THEN CURRENT_TIMESTAMP LINENO TO CURRENT_USER LOAD TOP CURSOR NATIONAL TRAN DATABASE NOCHECK TRANSACTION DBCC NONCLUSTERED TRIGGER DEALLOCATE NOT TRUNCATE DECLARE NULL TSEQUAL DEFAULT NULLIF UNION DELETE OF UNIQUE DENY OFF UPDATE DESC OFFSETS UPDATETEXT DISK ON USE DISTINCT OPEN USER DISTRIBUTED OPENDATASOURCE VALUES DOUBLE OPENQUERY VARYING DROP OPENROWSET VIEW DUMMY OPENXML WAITFOR DUMP OPTION WHEN ELSE OR WHERE END ORDER WHILE ERRLVL OUTER WITH ESCAPE OVER WRITETEXT";
 export default {
 name: "codeEditor",

 props: {
  options: {
  type: Object,
  default() {
   return {
   language: "java", // shell、sql、python
   readOnly: true // 不能编辑
   };
  }
  },

  value: {
  type: String,
  default: ""
  }
 },

 data() {
  return {
  monacoInstance: null,
  provider: null,
  hints: [
   "SELECT",
   "INSERT",
   "DELETE",
   "UPDATE",
   "CREATE TABLE",
   "DROP TABLE",
   "ALTER TABLE",
   "CREATE VIEW",
   "DROP VIEW",
   "CREATE INDEX",
   "DROP INDEX",
   "CREATE PROCEDURE",
   "DROP PROCEDURE",
   "CREATE TRIGGER",
   "DROP TRIGGER",
   "CREATE SCHEMA",
   "DROP SCHEMA",
   "CREATE DOMAIN",
   "ALTER DOMAIN",
   "DROP DOMAIN",
   "GRANT",
   "DENY",
   "REVOKE",
   "COMMIT",
   "ROLLBACK",
   "SET TRANSACTION",
   "DECLARE",
   "EXPLAN",
   "OPEN",
   "FETCH",
   "CLOSE",
   "PREPARE",
   "EXECUTE",
   "DESCRIBE",
   "FORM",
   "ORDER BY"
  ]
  };
 },
 created() {
  this.initHints();
 },
 mounted() {
  this.init();
 },
 beforeDestroy() {
  this.dispose();
 },

 methods: {
  dispose() {
  if (this.monacoInstance) {
   if (this.monacoInstance.getModel()) {
   this.monacoInstance.getModel().dispose();
   }
   this.monacoInstance.dispose();
   this.monacoInstance = null;
   if(this.provider){
   this.provider.dispose();
   this.provider = null
   }
  }
  },
  initHints() {
  let sqlArr = sqlStr.split(" ");
  this.hints = Array.from(new Set([...this.hints, ...sqlArr])).sort();
  },
  init() {
  let that = this;
  this.dispose();
  let createCompleters = textUntilPosition => {
   //过滤特殊字符
   let _textUntilPosition = textUntilPosition
   .replace(/[*[]@$()]/g, "")
   .replace(/(s+|.)/g, " ");
   //切割成数组
   let arr = _textUntilPosition.split(" ");
   //取当前输入值
   let activeStr = arr[arr.length - 1];
   //获得输入值的长度
   let len = activeStr.length;

   //获得编辑区域内已经存在的内容
   let rexp = new RegExp("([^\w]|^)"+activeStr+"\w*", "gim");
   let match = that.value.match(rexp);
   let _hints = !match ? [] : match.map(ele => {
   let rexp = new RegExp(activeStr, "gim");
   let search = ele.search(rexp);
   return ele.substr(search)
   })

   //查找匹配当前输入值的元素
   let hints = Array.from(new Set([...that.hints, ..._hints])).sort().filter(ele => {
   let rexp = new RegExp(ele.substr(0, len), "gim");
   return match && match.length === 1 && ele === activeStr || ele.length === 1
    ? false
    : activeStr.match(rexp);
   });
   //添加内容提示
   let res = hints.map(ele => {
   return {
    label: ele,
    kind: that.hints.indexOf(ele) > -1 ? monaco.languages.CompletionItemKind.Keyword : monaco.languages.CompletionItemKind.Text,
    documentation: ele,
    insertText: ele
   };
   });
   return res;
  };
  this.provider = monaco.languages.registerCompletionItemProvider("sql", {
   provideCompletionItems(model, position) {
   var textUntilPosition = model.getValueInRange({
    startLineNumber: position.lineNumber,
    startColumn: 1,
    endLineNumber: position.lineNumber,
    endColumn: position.column
   });
   var suggestions = createCompleters(textUntilPosition);
   return {
    suggestions: suggestions
   };

   return createCompleters(textUntilPosition);
   }
  });

  // 初始化编辑器实例
  this.monacoInstance = monaco.editor.create(this.$refs["container"], {
   value: this.value,
   theme: "vs-dark",
   autoIndex: true,
   ...this.options
  });

  // 监听编辑器content变化事件
  this.monacoInstance.onDidChangeModelContent(() => {
   this.$emit("contentChange", this.monacoInstance.getValue());
  });
  }
 }
 };
</script>

<style lang="scss" scope>
 .code-container {
 width: 100%;
 height: 100%;
 overflow: hidden;
 border: 1px solid #eaeaea;
 .monaco-editor .scroll-decoration {
  box-shadow: none;
 }
 }
</style>

引入页面,供本页面使用

index.vue

<template>
 <div class="container">
 <code-editor
  :options="options"
  :value="content"
  @contentChange="contentChange"
  style="height: 400px; width: 600px;"
 ></code-editor>
 </div>
</template>

<script>
 import CodeEditor from "@/components/CodeEditor";
 export default {
 name: "SQLEditor",
 components: {
  CodeEditor
 },
 data() {
  return {
  content: "",
  options: {
   language: "sql",
   theme: "vs",
   readOnly: false
  }
  };
 },
 created() {},
 methods: {
  // 绑定编辑器value值的变化
  contentChange(val) {
  this.content = val;
  }
 }
 };
</script>


<style scoped lang="scss">
 .container {
 text-align: left;
 padding: 10px;
 }
</style>

效果如下所示

代码自动提示效果,如下所示

vue 使用monaco实现代码高亮

代码高亮效果,代码段折叠效果,右侧预览效果如下所示

vue 使用monaco实现代码高亮

以上就是vue 使用monaco实现代码高亮的详细内容,更多关于vue 代码高亮的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/lgx211/p/12731594.html

标签:

相关文章

热门资讯

蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整 2021-08-24
2022年最旺的微信头像大全 微信头像2022年最新版图片
2022年最旺的微信头像大全 微信头像2022年最新版图片 2022-01-10
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
返回顶部