index.vue 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <!--
  2. * @Descripttion: 代码编辑器
  3. * @version: 1.0
  4. * @Author: sakuya
  5. * @Date: 2022年5月20日21:46:29
  6. * @LastEditors:
  7. * @LastEditTime:
  8. -->
  9. <template>
  10. <div class="sc-code-editor" :style="{ 'height': _height }">
  11. <textarea ref="textarea" v-model="contentValue"></textarea>
  12. </div>
  13. </template>
  14. <script>
  15. import CodeMirror from "codemirror";
  16. import "codemirror/lib/codemirror.css";
  17. // 主题
  18. import "codemirror/theme/idea.css";
  19. import "codemirror/theme/neat.css";
  20. // 功能
  21. import "codemirror/addon/selection/active-line";
  22. // 语言
  23. import "codemirror/mode/javascript/javascript";
  24. export default {
  25. props: {
  26. modelValue: { type: String, default: "" },
  27. mode: { type: String, default: "javascript" },
  28. height: { type: [String, Number], default: 300 },
  29. options: { type: Object, default: () => {} },
  30. theme: { type: String, default: "neat" },
  31. readOnly: { type: Boolean, default: false }
  32. },
  33. data() {
  34. return {
  35. contentValue: this.modelValue,
  36. coder: null,
  37. opt: {
  38. theme: this.theme, // 主题
  39. styleActiveLine: true, // 高亮当前行
  40. lineNumbers: true, // 行号
  41. lineWrapping: false, // 自动换行
  42. tabSize: 4, // Tab缩进
  43. indentUnit: 4, // 缩进单位
  44. indentWithTabs : true, // 自动缩进
  45. mode : this.mode, // 语言
  46. readOnly: this.readOnly, // 只读
  47. ...this.options
  48. }
  49. }
  50. },
  51. computed: {
  52. _height() {
  53. return Number(this.height) ? Number(this.height) + "px" : this.height
  54. }
  55. },
  56. watch: {
  57. modelValue(val) {
  58. this.contentValue = val;
  59. if (val !== this.coder.getValue()) this.coder.setValue(val);
  60. }
  61. },
  62. mounted() {
  63. this.init();
  64. },
  65. methods: {
  66. init() {
  67. this.coder = markRaw(CodeMirror.fromTextArea(this.$refs.textarea, this.opt));
  68. this.coder.on("change", coder => {
  69. this.contentValue = coder.getValue();
  70. this.$emit("update:modelValue", this.contentValue);
  71. });
  72. }
  73. }
  74. }
  75. </script>
  76. <style scoped>
  77. .sc-code-editor {font-size: 14px;border: 1px solid #ddd;line-height: 150%;}
  78. .sc-code-editor:deep(.CodeMirror) {height: 100%;}
  79. </style>