MonacoEditor.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <!--
  2. * @Descripttion:
  3. * @version:
  4. * @Author: qianlishi
  5. * @Date: 2021-8-6 14:48:27
  6. * @LastEditors: qianlishi
  7. * @LastEditTime: 2021-12-13 18:48:24
  8. -->
  9. <template>
  10. <div ref="editor" class="main"></div>
  11. </template>
  12. <script>
  13. import * as monaco from "monaco-editor";
  14. import createSqlCompleter from "./util/sql-completion";
  15. import createJavascriptCompleter from "./util/javascript-completion";
  16. import registerLanguage from "./util/log-language";
  17. const global = {};
  18. const getHints = model => {
  19. let id = model.id.substring(6);
  20. return (global[id] && global[id].hints) || [];
  21. };
  22. monaco.languages.registerCompletionItemProvider(
  23. "sql",
  24. createSqlCompleter(getHints)
  25. );
  26. monaco.languages.registerCompletionItemProvider(
  27. "javascript",
  28. createJavascriptCompleter(getHints)
  29. );
  30. registerLanguage(monaco);
  31. /**
  32. * monaco options
  33. * https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandaloneeditorconstructionoptions.html
  34. */
  35. export default {
  36. props: {
  37. options: {
  38. type: Object,
  39. default() {
  40. return {};
  41. }
  42. },
  43. value: {
  44. type: String,
  45. required: false
  46. },
  47. language: {
  48. type: String
  49. },
  50. hints: {
  51. type: Array,
  52. default() {
  53. return [];
  54. }
  55. }
  56. },
  57. name: "MonacoEditor",
  58. data() {
  59. return {
  60. editorInstance: null,
  61. defaultOptions: {
  62. theme: "vs-dark",
  63. fontSize: 14
  64. }
  65. };
  66. },
  67. watch: {
  68. value() {
  69. if (this.value !== this.editorInstance.getValue()) {
  70. this.editorInstance.setValue(this.value);
  71. }
  72. }
  73. },
  74. mounted() {
  75. this.initEditor();
  76. global[this.editorInstance._id] = this;
  77. window.addEventListener("resize", this.layout);
  78. },
  79. destroyed() {
  80. this.editorInstance.dispose();
  81. global[this.editorInstance._id] = null;
  82. window.removeEventListener("resize", this.layout);
  83. },
  84. methods: {
  85. layout() {
  86. this.editorInstance.layout();
  87. },
  88. undo() {
  89. this.editorInstance.trigger("anyString", "undo");
  90. this.onValueChange();
  91. },
  92. redo() {
  93. this.editorInstance.trigger("anyString", "redo");
  94. this.onValueChange();
  95. },
  96. getOptions() {
  97. let props = { value: this.value };
  98. this.language !== undefined && (props.language = this.language);
  99. let options = Object.assign({}, this.defaultOptions, this.options, props);
  100. return options;
  101. },
  102. onValueChange() {
  103. this.$emit("input", this.editorInstance.getValue());
  104. this.$emit("change", this.editorInstance.getValue());
  105. },
  106. initEditor() {
  107. this.MonacoEnvironment = {
  108. getWorkerUrl: function() {
  109. return "./editor.worker.bundle.js";
  110. }
  111. };
  112. this.editorInstance = monaco.editor.create(
  113. this.$refs.editor,
  114. this.getOptions()
  115. );
  116. this.editorInstance.onContextMenu(e => {
  117. this.$emit("contextmenu", e);
  118. });
  119. this.editorInstance.onDidChangeModelContent(() => {
  120. this.onValueChange();
  121. });
  122. this.editorInstance.addCommand(
  123. monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S,
  124. () => {
  125. this.$emit("save", this.editorInstance.getValue());
  126. }
  127. );
  128. }
  129. }
  130. };
  131. </script>
  132. <style scoped>
  133. .main /deep/ .view-lines * {
  134. font-family: Consolas, "Courier New", monospace !important;
  135. }
  136. </style>