vue-codemirror使用教程 左侧编辑代码右侧显示页面实现代码编辑并实时预览

网上找了很多都是只是简单的编辑,我自己整理了一下开发了一个一边编辑一边显示的方法 现在把学习过程分享一下

在这里插入图片描述

第一步下载依赖包

npm install vue-codemirror --save
注意:最新版本只能在vue3使用 vue3 以下需要指定版本
Legacy version
examples (Vue2)
vue-codemirror@4.x (Vue2 / CodeMirror5)[添加链接描述](https://www.npmjs.com/package/vue-codemirror)

npm i codemirror 和vue-codemirror 配套使用vue-codemirror只是一个封装的组件
npm i vue-clipboard2 复制用的

main.js引入复制库

import VueClipboard from 'vue-clipboard2'
Vue.use(VueClipboard)

代码编辑组件

 <!-- 代码编辑 -->
<template>
  <div class="experience-editor">
    <div class="experience-editor-header">
      <div class="experience-editor-header-title">源代码编辑器</div>
      <div class="experience-editor-header-right">
        <div class="experience-editor-header-right-box"
             v-clipboard:copy="code"
             v-clipboard:success="onCopy"
             v-clipboard:error="onError">
          <i class="el-icon-document-copy"></i>
          复制
        </div>
        <div class="experience-editor-header-right-box"
             @click="play">
          <i class="el-icon-video-play"></i>
          运行
        </div>
        <div class="experience-editor-header-right-box"
             @click="refresh">
          <i class="el-icon-refresh"></i>
          刷新
        </div>
        <div class="experience-editor-header-right-box" @click="download('index.html',code)">
          <i class="el-icon-download"></i>
           下载
        </div>
      </div>
    </div>
    <codemirror ref="myCm"
                v-model="code"
                :options="cmOptions"
                @changes="onChanges"
                class="experience-editor-code"></codemirror>
  </div>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
// 引用

import { codemirror } from 'vue-codemirror';
import 'codemirror/lib/codemirror.css';
import 'codemirror/theme/3024-day.css'; // 引入主题样式,根据设置的theme的主题引入
import 'codemirror/mode/htmlmixed/htmlmixed.js'; // html代码高亮
import { viewObj } from '../../utils/view';
export default {
    //import引入的组件需要注入到对象中才能使用
    name: 'experience-editor',
    components: {},
    data() {
        //这里存放数据
        return {
            baseCode: '',
            code: '',
            codePath: '../',
            cmOptions: {
                tabSize: 4,
                mode: 'htmlmixed', // htmlcssjs可以用这个,其他语言可以看官网的参数
                theme: '3024-day', // 主题和引入对应
                lineWrapping: true, // 自动换行
                lineNumbers: true
            }
        };
    },
    //监听属性 类似于data概念
    computed: {},
    //监控data中的数据变化
    watch: {},
    created() {},
    components: {
        codemirror
    },
    computed: {},
    methods: {
        //下载
        download(filename, text) {
            var element = document.createElement('a');
            element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
            element.setAttribute('download', filename);
            element.style.display = 'none';
            document.body.appendChild(element);

            element.click();
            document.body.removeChild(element);
        },
        play() {
            // 调用父组件的方法
            this.$parent.writeCode(this.code);
        },
        refresh() {
            this.code = this.baseCode;
            this.$parent.writeCode(this.baseCode);
        },
        // 复制成功时的回调函数
        onCopy(e) {
            this.$message.success('内容已复制到剪切板!'); // 使用的element-ui插件
        },
        // 复制失败时的回调函数
        onError(e) {
            this.$message.error('抱歉,复制失败!');
        },
        onChanges() {
            this.code = this.$refs.myCm.content;
        }
    },
    //生命周期 - 创建完成(可以访问当前this实例)
    created() {},
    //生命周期 - 挂载完成(可以访问DOM元素)
    mounted() {
        this.code = viewObj[this.$route.params.id];
        this.baseCode = this.code;
    },
    beforeCreate() {}, //生命周期 - 创建之前
    beforeMount() {}, //生命周期 - 挂载之前
    beforeUpdate() {}, //生命周期 - 更新之前
    updated() {}, //生命周期 - 更新之后
    beforeDestroy() {}, //生命周期 - 销毁之前
    destroyed() {}, //生命周期 - 销毁完成
    activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style lang='less' scoped>
//@import url(); 引入公共css类
.experience-editor-header {
    display: flex;
    height: 45px;
    line-height: 45px;
    background-color: #f3f4f8;
    justify-content: space-between;
    padding-left: 10px;
}
.experience-editor-header-right {
    display: flex;
    padding: 0 10px;
    .experience-editor-header-right-box {
        cursor: pointer;
        margin-right: 10px;
    }
}
.experience-editor-code {
    height: 100%;
}
</style>

父组件 左侧显示编辑代码 右侧显示页面 主要原理是 iframe

<!-- 百度地图示例页面 -->
<template>
    <div class="experience-main">
      <experience-editor style="width: 40%;height: 100%;"></experience-editor>
      <iframe src="about:blank#"
              unselectable="on"
              frameborder="0"
              scrolling="no"
              style="width:60%;height:100%;"
              ref="myIframe"
              id="codeIframe"
              allowfullscreen></iframe>
    </div>
  </template>
  
  <script>
  //这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  //例如:import 《组件名称》 from '《组件路径》';
  import ExperienceEditor from '../common/experience-editor.vue';
  import {viewObj} from '../../utils/view'
  export default {
      //import引入的组件需要注入到对象中才能使用
      components: { ExperienceEditor },
      data() {
          //这里存放数据
          return {
             
          };
      },
      //监听属性 类似于data概念
      computed: {},
      //监控data中的数据变化
      watch: {},
      //方法集合
      methods: {
          // 向iframe空页面写代码
          writeCode(code) {
              const iframe = document.querySelector('#codeIframe');
              iframe.contentWindow.document.open();
              iframe.contentWindow.document.write(code);
              iframe.contentWindow.document.close();
          }
      },
      //生命周期 - 创建完成(可以访问当前this实例)
      created() {},
      //生命周期 - 挂载完成(可以访问DOM元素)
      mounted() {
          this.writeCode(viewObj[this.$route.params.id]);
      },
      beforeCreate() {}, //生命周期 - 创建之前
      beforeMount() {}, //生命周期 - 挂载之前
      beforeUpdate() {}, //生命周期 - 更新之前
      updated() {}, //生命周期 - 更新之后
      beforeDestroy() {}, //生命周期 - 销毁之前
      destroyed() {}, //生命周期 - 销毁完成
      activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
  };
  </script>
  <style lang='less' scoped>
  //@import url(); 引入公共css类
  .experience-main {
      width: 100%;
      height: 100%;
      display: flex;
  }
  </style>

封装的代码数据 因为我做的是根据菜单栏切换 所以页面代码才用枚举,通过路由参数显示当前要显示的也买

import { html01 } from '../static/data/mapShow/mapShow01';
var viewObj = {
    '01':html01
}
export {viewObj}

代码

var html01 =`
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        44
    </body>
    </html>
`
export {html01}

### 如何在前端项目中集成和使用 sql-formatter 工具 要在前端项目中集成使用 `sql-formatter` 来格式化 SQL 语句,可以按照以下方法操作: #### 安装依赖 通过 npm 或 yarn 将 `sql-formatter` 添加到项目的依赖项中。 ```bash npm install --save sql-formatter@2.3.3 ``` 或者, ```bash yarn add sql-formatter@2.3.3 ``` 此安装命令会将指定版本的 `sql-formatter` 插件下载至项目目录下[^1]。 --- #### 引入模块 在需要使用页面或组件文件中引入 `sql-formatter` 模块。以下是具体的实现方式: ```javascript import sqlFormatter from "sql-formatter"; const rawSql = ` CREATE TABLE IF NOT EXISTS \`test_user\`.\`testA_\` ( \`hello\` VARCHAR(255) COMMENT '你好', \`world\` VARCHAR(255) COMMENT '世界' ) COMMENT '测试' STORED AS PARQUET; `; // 使用 format 方法对原始 SQL 进行格式化处理 let formattedSql = sqlFormatter.format(rawSql); console.log(formattedSql); ``` 上述代码展示了如何加载未格式化的 SQL 字符串通过调用 `format()` 函数将其转换为易于阅读的形式。 --- #### 自定义配置选项 如果希望进一步调整格式化行为,可以通过传递参数来自定义设置。例如,控制缩进大小、强制大写关键字等。 ```javascript const customFormattedSql = sqlFormatter.format(rawSql, { indent: " ", // 设置每级缩进为空格数,默认为两个空格 uppercase: true, // 是否将关键词转为大写形式 }); console.log(customFormattedSql); ``` 这些自定义选项允许开发者更灵活地满足特定需求。 --- #### 结合 VueCodeMirror 实现动态展示 对于基于 Vue 的项目,还可以借助 `vue-codemirror` 组件库增强用户体验。下面是一个简单的例子说明如何结合两者完成 SQL 编辑实时预览功能。 ##### 步骤一:安装 vue-codemirror 及其样式表 ```bash npm install codemirror vue-codemirror --save ``` ##### 步骤二:创建 Vue 组件 编写一个支持 SQL 输入框以及即时显示已格式化结果的小部件。 ```html <template> <div> <!-- 原始输入 --> <codemirror v-model="rawInput" :options="editorOptions"></codemirror> <!-- 格式化后的输出 --> <pre>{{ formattedOutput }}</pre> </div> </template> <script> import { Codemirror } from "vue-codemirror"; import "codemirror/lib/codemirror.css"; // 导入默认主题 CSS 文件 import sqlFormatter from "sql-formatter"; export default { components: { Codemirror }, data() { return { rawInput: "", // 用户键入的内容 editorOptions: { mode: "text/x-sql", // 设定语法高亮模式为 SQL lineNumbers: true, theme: "default", }, }; }, computed: { formattedOutput() { try { const result = sqlFormatter.format(this.rawInput, { indent: "\t", // 制表位作为缩进单位 uppercase: false, // 关闭自动转换成全大写字母的功能 }); return result || ""; } catch (error) { console.error(error.message); // 处理可能发生的错误情况 return this.rawInput; // 如果失败则返回原样字符串 } }, }, }; </script> ``` 在此示例中,当用户修改左侧区域中的内容时,右侧部分会立即更新以反映经过整理的新版 SQL 表达式。 --- ### 注意事项 尽管 `sql-formatter` 提供了强大的基础能力,但在某些复杂场景下的表现可能会有所局限。因此,在实际应用前建议先验证目标环境兼容性和预期效果的一致性[^2]^。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值