vue language is used, and component of element is used. To make an online editing code, code content is required to be input, highlighted display can be carried out, different languages can be switched, keyword completion is supported, and a code left-right comparison between different versions is required.
As for why codemirror is selected, please check A comprehensive comparison of code highlighting plug-ins in vue (element)
OK, let's start work now!
First, you need to download the codemirror component and the diff match patch component
npm install codemirror npm install diff-match-patch
Of course, npm download is very slow, change a domestic image, Taobao. Sure enough, the speed swished.
npm install -g cnpm --registry=https://registry.npm.taobao.org cnpm install cnpm install codemirror cnpm install diff-match-patch
You can see the directory structure under node modules
The core code is as follows, which is simple and easy to understand. You can customize the development according to yourself.
<template> <div> <!-- Operation button --> <el-button @click="handleAdd">Code editing, highlight completion</el-button> <el-button @click="handleMerge">Code version, difference comparison</el-button> <!-- Code editing, highlight the content of the completion dialog box --> <el-dialog :title="title" :visible.sync="open"> <el-form ref="form" :model="form" label-width="80px"> <el-form-item label="Script content"> <div class="in-coder-panel"> <textarea ref="textarea"></textarea> <el-select class="code-mode-select" v-model="mode" @change="changeMode"> <el-option v-for="mode in modes" :key="mode.value" :label="mode.label" :value="mode.value"> </el-option> </el-select> </div> </el-form-item> </el-form> </el-dialog> <!-- Code version, difference comparison dialog content --> <el-dialog :title="titleBBB" :visible.sync="openBBB"> <div id="view"></div> </el-dialog> </div> </template> <script> // Introduce global instance import CodeMirror from 'codemirror' // Core style import 'codemirror/lib/codemirror.css' // After the theme is introduced, you need to specify the theme in options to take effect import 'codemirror/theme/idea.css' // You need to introduce a specific syntax highlighting library to have the corresponding syntax highlighting effect // codemirror officially supports dynamic loading of corresponding syntax highlight library through / addon/mode/loadmode.js and / mode/meta.js // However, vue does not seem to be able to dynamically load the corresponding JS after instance initialization, so the corresponding JS is introduced in advance here import 'codemirror/mode/javascript/javascript.js' import 'codemirror/mode/css/css.js' import 'codemirror/mode/xml/xml.js' import 'codemirror/mode/shell/shell.js' import 'codemirror/mode/sql/sql.js' //Code completion prompt import 'codemirror/addon/hint/anyword-hint.js'; import 'codemirror/addon/hint/css-hint.js'; import 'codemirror/addon/hint/html-hint.js'; import 'codemirror/addon/hint/javascript-hint.js'; import 'codemirror/addon/hint/show-hint.css'; import 'codemirror/addon/hint/show-hint.js'; import 'codemirror/addon/hint/sql-hint.js'; import 'codemirror/addon/hint/xml-hint.js'; //Code version difference comparison import 'codemirror/addon/merge/merge.js' import 'codemirror/addon/merge/merge.css' import DiffMatchPatch from 'diff-match-patch' window.diff_match_patch = DiffMatchPatch window.DIFF_DELETE = -1 window.DIFF_INSERT = 1 window.DIFF_EQUAL = 0 export default { name: "Code", props: { // External incoming content for two-way binding value: String, // Syntax type passed in from outside language: { type: String, default: null } }, data() { return { // What's real inside code: '#!/bin/bash\n' + 'cd /root/\n' + 'list=(`ls`)\n' + ' \n' + 'for i in ${list[@]}\n' + 'do\n' + ' if [ -d $i ]\n' + ' then\n' + ' cp -r $i /tmp/\n' + ' fi\n' + 'done', // Default syntax type mode: 'shell', // Editor instance coder: null, // Default configuration options: { // Indentation format tabSize: 4, // Subject, corresponding subject library JS needs to be introduced in advance theme: 'idea', // set number lineNumbers: true, line: true, extraKeys: {"Ctrl": "autocomplete"}, }, // The syntax highlighting type that supports switching. The corresponding JS has been introduced in advance // MIME type is used, but text / as prefix is written dead when specified later modes: [{ value: 'css', label: 'CSS' }, { value: 'javascript', label: 'Javascript' }, { value: 'html', label: 'XML/HTML' }, { value: 'x-sh', label: 'Shell' }, { value: 'x-sql', label: 'SQL' }], // Pop up layer title title: "", titleBBB: "", // Show pop-up layer or not open: false, openBBB: false, }, methods: { // Initialization _initialize() { // Initialize the editor instance, pass in the text field object and default configuration to be instantiated this.coder = CodeMirror.fromTextArea(this.$refs.textarea, this.options) // Editor assignment this.coder.setValue(this.value || this.code) // Supports two-way binding this.coder.on('change', (coder) => { this.code = coder.getValue() if (this.$emit) { this.$emit('input', this.code) } }) // Attempt to get syntax type from parent container if (this.language) { // Get specific syntax type object let modeObj = this._getLanguage(this.language) // Determine whether the syntax passed in by the parent container is supported if (modeObj) { this.mode = modeObj.label } } }, // Get the current syntax type _getLanguage(language) { // Find the incoming syntax type in the list of supported syntax types return this.modes.find((mode) => { // All values ignore case for comparison let currentLanguage = language.toLowerCase() let currentLabel = mode.label.toLowerCase() let currentValue = mode.value.toLowerCase() // Because the real value may not be standardized, for example, the real value of Java is x-java, so it is said that value and label are compared with the incoming syntax at the same time return currentLabel === currentLanguage || currentValue === currentLanguage }) }, // Change mode changeMode(val) { // Modify the syntax configuration of the editor this.coder.setOption('mode', `text/${val}`) // Get the modified syntax let label = this._getLanguage(val).label.toLowerCase() // Allows the parent container to listen for the current syntax value through the following functions this.$emit('language-change', label) }, initUI(value, orig) { if (value == null) return; let target = document.getElementById("view"); target.innerHTML = ""; CodeMirror.MergeView(target, { value: value,//Last content origLeft: null, orig: orig,//This content lineNumbers: true,//set number mode: "shell", highlightDifferences: true, styleActiveLine: true, matchBrackets: true, connect: 'align', readOnly: true,//Read only and immutable }); }, /** Button operation */ handleAdd() { this.open = true; this.title = "Code editing, highlight completion"; this.$nextTick(function () { this._initialize(); }); }, /** Button operation */ handleUpdateBBB() { this.openBBB = true; this.titleBBB = "Code version, difference comparison"; // Initialize version differences this.$nextTick(function () { this.initUI("#!/bin/bash\n" + "ip=\"123.21.12.11\"\n" + "email=\"lgx@example\"\n" + " \n" + "while 1\n" + "do\n" + " ping -c10 $ip > /dev/null 2>/dev/null\n" + " if [ $? != \"0\" ]\n" + " then\n" + " # Call a script to send mail \ n "+ " python /usr/local/sbin/mail.py $email \"$ip down\" \"$ip is down\"\n" + " fi\n" + " sleep 30\n" + "done", "#!/bin/bash\n" + "ip=\"123.21.12.11\"\n" + "email=\"admin@example\"\n" + " \n" + "while 1\n" + "do\n" + " ping -c10 $ip > /dev/null 2>/dev/null\n" + " if [ $? != \"0\" ]\n" + " then\n" + " # Call a script to send mail \ n "+ " python /usr/local/sbin/mail.py $email \"$ip down\" \"$ip is down\"\n" + " fi\n" + "done") }); }, } }; </script> <style lang="stylus" rel="stylesheet/stylus"> .in-coder-panel flex-grow 1 display flex position relative .CodeMirror flex-grow 1 z-index 1 .CodeMirror-code line-height 19px .code-mode-select position absolute z-index 2 right 10px top 10px max-width 130px </style>
After running, the code highlights as follows;
After running, on the code auto completion effect class, I bind the Ctrl key, input the first few letters of the keyword, and press and hold the Ctrl key to automatically complete according to the selected language;
After running, the code version difference comparison effect is as follows:;
Scroll either side of the vertical scroll bar or the horizontal scroll bar, the other side will also move with the amplitude.