当前位置:   article > 正文

vite+ts使用vue-codemirror实现sql、js代码编辑器_vite ts codemirror5

vite ts codemirror5
实现效果,ui库选择的是最新的naive-ui库,根据自己需要选择合适的库即可

一、安装依赖
npm install vue-codemirror --save

 同时安装使用sql/javascript语言的代码编辑器,根据自己需要选择

  1. npm install @codemirror/lang-sql
  2. npm install @codemirror/lang-javascript

如果想要黑色编辑器的主题, 可在命令行安装

npm i  @codemirror/theme-one-dark

对SQL代码进行格式化/清空功能

1、npm安装sql-formatter插件

npm install sql-formatter --save

 2、引入该sql-formatter.js文件

import sqlFormatter from 'sql-formatter';
二、封装公共组件 MyCodeEdit.vue 完整代码如下:
  1. <template>
  2. <codemirror
  3. ref="codeEdit"
  4. v-model="sqlCode"
  5. :placeholder="editorPlaceholder"
  6. :style="{ height: editorHeight + 'px' }"
  7. :autofocus="true"
  8. :indent-with-tab="true"
  9. :tabSize="tabSize"
  10. :extensions="extensions"
  11. :scrollbarStyle="null"
  12. @change="emit('change', $event)"
  13. />
  14. <div class="sql-format">
  15. <div class="theme">
  16. <span style="margin-right: 6px">主题</span>
  17. <n-switch :size="'small'" :value="theme" @click="handleTheme"></n-switch>
  18. </div>
  19. <span @click="formatSql" style="margin: 0 10px">格式化SQL</span>
  20. <span @click="clearVal">一键清空</span>
  21. </div>
  22. </template>
  23. <script setup>
  24. import { Codemirror } from "vue-codemirror";
  25. import { sql } from "@codemirror/lang-sql";
  26. import { defineEmits, ref, defineProps, computed, watch } from "vue";
  27. import { NSwitch, NSpace } from "naive-ui";
  28. import * as sqlFormatter from "sql-formatter";
  29. import { oneDark } from "@codemirror/theme-one-dark";
  30. const emit = defineEmits();
  31. const props = defineProps({
  32. value: {
  33. type: String,
  34. default: "",
  35. },
  36. editorPlaceholder: {
  37. type: String,
  38. default: "请输入代码",
  39. },
  40. editorHeight: {
  41. type: String,
  42. default: "300",
  43. },
  44. tabSize: {
  45. type: Number,
  46. default: 2,
  47. },
  48. });
  49. const codeEdit = ref();
  50. const theme = ref(false);
  51. const sqlCode = ref();
  52. watch(
  53. () => props.value,
  54. () => {
  55. sqlCode.value = props.value;
  56. },
  57. {
  58. immediate: true,
  59. deep: true,
  60. }
  61. );
  62. const extensions = ref([sql()]);
  63. function handleTheme() {
  64. console.log(theme.value);
  65. theme.value = !theme.value;
  66. theme.value
  67. ? (extensions.value = [sql(), oneDark])
  68. : (extensions.value = [sql()]);
  69. }
  70. //代码格式化
  71. const formatSql = () => {
  72. sqlCode.value = sqlFormatter.format(sqlCode.value);
  73. };
  74. // 清除值
  75. const clearVal = () => {
  76. sqlCode.value = "";
  77. };
  78. </script>
  79. <style scoped lang="scss">
  80. .sql-format {
  81. background-color: #f7f7f7;
  82. display: flex;
  83. justify-content: flex-end;
  84. color: #2a99ff;
  85. padding: 10px;
  86. .theme {
  87. display: flex;
  88. justify-content: center;
  89. align-items: center;
  90. }
  91. & > span:hover {
  92. cursor: pointer;
  93. text-decoration: underline;
  94. }
  95. > span:first-child {
  96. margin-right: 10px;
  97. }
  98. }
  99. </style>
三、页面中使用,我这里实在弹框中使用的 根据需要修改
  1. <template>
  2. <n-modal
  3. v-model:show="props.show"
  4. :show-icon="false"
  5. @update:show="$emit('update:show')"
  6. preset="dialog"
  7. style="width: 80%"
  8. :title="title"
  9. >
  10. <div class="code-editor">
  11. <n-form
  12. :model="formParams"
  13. :rules="rules"
  14. ref="formRef"
  15. label-placement="top"
  16. :label-width="120"
  17. class="py-4"
  18. :label-align="'left'"
  19. >
  20. <n-form-item label="自定义查询名称" path="sqlName">
  21. <n-input v-model:value="formParams.sqlName" clearable />
  22. </n-form-item>
  23. </n-form>
  24. <div class="code-label">SQL编辑区域</div>
  25. <sql-code-edit
  26. :value="formParams.sqlCode"
  27. :editor-placeholder="'请输入sql语句'"
  28. :editor-height="'300'"
  29. :tab-size="4"
  30. @change="changeSqlCode"
  31. />
  32. </div>
  33. <template #action>
  34. <n-space>
  35. <n-button
  36. v-show="view === false"
  37. type="primary"
  38. :loading="formBtnLoading"
  39. @click="confirmForm"
  40. >保存</n-button
  41. >
  42. <n-button @click="emit('update:show')">取消</n-button>
  43. </n-space>
  44. </template>
  45. </n-modal>
  46. </template>
  47. <script lang="ts" setup>
  48. import {
  49. computed,
  50. onBeforeUpdate,
  51. onMounted,
  52. reactive,
  53. ref,
  54. watch,
  55. withDefaults,
  56. unref,
  57. onUpdated,
  58. watchEffect,
  59. } from "vue";
  60. import {
  61. useMessage,
  62. FormItemRule,
  63. TreeSelectOption,
  64. NLog,
  65. NScrollbar,
  66. NText,
  67. NH6,
  68. NInputNumber,
  69. NButton,
  70. } from "naive-ui";
  71. import { each, cloneDeep, filter, find, groupBy } from "lodash-es";
  72. import SqlCodeEdit from "./coms/MyCodeEdit.vue";
  73. const isEdit = computed(() => !!props.current?.id);
  74. const title = computed(() => (isEdit.value ? "编辑" : "新增"));
  75. const message = useMessage();
  76. interface IProps {
  77. show?: boolean;
  78. current?: Record<string, any> | null;
  79. view?: boolean;
  80. params?: any;
  81. }
  82. const props = withDefaults(defineProps<IProps>(), {
  83. show: false,
  84. view: false,
  85. });
  86. const formRef = ref();
  87. // 子组件向父组件传值
  88. const emit = defineEmits<{
  89. (e: "update:show"): void;
  90. (e: "reloadTable"): void;
  91. }>();
  92. const formParams = reactive<any>({
  93. sqlName: "",
  94. sqlCode: "",
  95. });
  96. // 定义表单
  97. const INIT_MODEL = {
  98. id: "",
  99. sqlName: "",
  100. sqlCode: "",
  101. };
  102. // 实时获取sql语句
  103. const changeSqlCode = (val: any) => {
  104. formParams.sqlCode = val;
  105. };
  106. function handleSave() {
  107. console.log(formParams);
  108. }
  109. // 验证规则
  110. const rules = {
  111. sqlName: {
  112. required: true,
  113. trigger: ["blur", "input"],
  114. message: "请输入查询名称",
  115. },
  116. };
  117. const formBtnLoading = ref(false);
  118. // 表单提交
  119. function confirmForm(e: any) {
  120. e.preventDefault();
  121. formBtnLoading.value = true;
  122. formRef.value.validate(async (errors: any) => {
  123. if (!errors) {
  124. setTimeout(() => {
  125. const params = { ...formParams };
  126. console.log(params);
  127. emit("update:show");
  128. emit("reloadTable");
  129. });
  130. } else {
  131. message.error("请填写完整信息");
  132. }
  133. formBtnLoading.value = false;
  134. });
  135. }
  136. watchEffect(() => {
  137. if (props.show) {
  138. each(INIT_MODEL, (v, field) => {
  139. formParams[field] = props.current?.[field];
  140. });
  141. } else {
  142. Object.keys(formParams).forEach((item) => {
  143. formParams[item] = null;
  144. });
  145. }
  146. });
  147. </script>
  148. <style scoped lang="scss">
  149. .sql-format {
  150. background-color: #f7f7f7;
  151. text-align: right;
  152. color: #2a99ff;
  153. padding: 10px;
  154. span:hover {
  155. cursor: pointer;
  156. text-decoration: underline;
  157. }
  158. > span:first-child {
  159. margin-right: 10px;
  160. }
  161. }
  162. </style>

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号