文章目录
- 1-1 代码高亮显示但不可以实现编辑输入vue-highlightjs
- 1-1-1 vue3
- 1-1-2 vue2
- 1-2 编辑输入高亮代码,进行格式规范code-mirror
- 1-2-1 展示
- 1-2-2 基本配置
- 1-2-3 使用
1-1 代码高亮显示但不可以实现编辑输入vue-highlightjs
1-1-1 vue3
- 安装依赖
npm install --save highlight.js
npm install --save @highlightjs/vue-plugin
- 页面单独饮用插件,不需要在main.ts全局使用
- 因为插件不支持响应式数据,所以不要使用ref响应式变量
<template> <highlightjs autodetect :code="jsonCode" /> </template> <script> import 'highlight.js/styles/stackoverflow-light.css';// 可以切换其它样式风格,例如黑色主题 import 'highlight.js/lib/common'; import hljsVuePlugin from "@highlightjs/vue-plugin"; export default { setup() { const jsonStr = [ { 'name': 'JSON', 'address': '北京市西城区', 'age': 25 }, { 'name': 'JSON', 'address': '北京市西城区', 'age': 25 } ]; let jsonCode = JSON.stringify(jsonStr, null, 2); // 设置tab为两个空格 return { jsonCode, }; }, components: { highlightjs: hljsVuePlugin.component } } </script>
1-1-2 vue2
- 安装
npm install --save vue-highlightjs npm install --save highlight.js
- 两个依赖:
- vue-highlight.js实现了代码高亮的功能
- 安装一个highlight.js来实现真正的样式。
- 两个依赖:
- 入口文件main.js中引用依赖
import VueHighlightJS from 'vue-highlightjs' import 'highlight.js/styles/atom-one-dark.css' Vue.use(VueHighlightJS)
- 使用
<pre v-highlightjs=codeDate ><code class="java"></code></pre>
- class内的java为对应要设置高亮的脚本语言
- javascript :
<code class="javascript "></code>
-
如遇版本问题会提示:
npm install --save highlight.js/lib/highlight highlight.js/styles/github-gist.css
-
对比json文件的版本和依赖版本是否一致,不一致安装为依赖的版本
code-mirror官网
之前参考过的相关文章:
- vue实现代码块高亮显示
- Vue中如何实现代码高亮功能?
1-2 编辑输入高亮代码,进行格式规范code-mirror
1-2-1 展示
可以输入
1-2-2 基本配置
-
在Web端实现在线代码编译的效果,那么需要使用组件vue-codemirror,他是将CodeMirror进行了再次封装
- 支持代码高亮
- 62种主题颜色,例如monokai等等
- 支持json, sql, javascript,css,xml, html,yaml, markdown,
- python编辑模式,默认为 json
- 支持快速搜索
- 支持自动补全提示
- 支持自动匹配括号
-
下载环境
npm install jshint npm install jsonlint npm install script-loader npm install vue-codemirror
1-2-3 使用
- 我们可以在项目中的components中将vue-codemirror进行再次封装
- vueCodemirror组件
<template>
<div>
<codemirror
ref="myCm"
:value="editorValue"
:options="cmOptions"
@changes="onCmCodeChanges"
@blur="onCmBlur"
@keydown.native="onKeyDown"
@mousedown.native="onMouseDown"
@paste.native="OnPaste"
/>
</div>
</template>
<script>
import { codemirror } from 'vue-codemirror'
import 'codemirror/keymap/sublime'
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/xml/xml.js'
import 'codemirror/mode/htmlmixed/htmlmixed.js'
import 'codemirror/mode/css/css.js'
import 'codemirror/mode/yaml/yaml.js'
import 'codemirror/mode/sql/sql.js'
import 'codemirror/mode/python/python.js'
import 'codemirror/mode/markdown/markdown.js'
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/javascript-hint.js'
import 'codemirror/addon/hint/xml-hint.js'
import 'codemirror/addon/hint/css-hint.js'
import 'codemirror/addon/hint/html-hint.js'
import 'codemirror/addon/hint/sql-hint.js'
import 'codemirror/addon/hint/anyword-hint.js'
import 'codemirror/addon/lint/lint.css'
import 'codemirror/addon/lint/lint.js'
// import 'codemirror/addon/lint/json-lint'
import 'codemirror/addon/selection/active-line'
import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/anyword-hint.js'
require('script-loader!jsonlint')
import 'codemirror/addon/lint/javascript-lint.js'
import 'codemirror/addon/fold/foldcode.js'
import 'codemirror/addon/fold/foldgutter.js'
import 'codemirror/addon/fold/foldgutter.css'
import 'codemirror/addon/fold/brace-fold.js'
import 'codemirror/addon/fold/xml-fold.js'
import 'codemirror/addon/fold/comment-fold.js'
import 'codemirror/addon/fold/markdown-fold.js'
import 'codemirror/addon/fold/indent-fold.js'
import 'codemirror/addon/edit/closebrackets.js'
import 'codemirror/addon/edit/closetag.js'
import 'codemirror/addon/edit/matchtags.js'
import 'codemirror/addon/edit/matchbrackets.js'
import 'codemirror/addon/selection/active-line.js'
import 'codemirror/addon/search/jump-to-line.js'
import 'codemirror/addon/dialog/dialog.js'
import 'codemirror/addon/dialog/dialog.css'
import 'codemirror/addon/search/searchcursor.js'
import 'codemirror/addon/search/search.js'
import 'codemirror/addon/display/autorefresh.js'
import 'codemirror/addon/selection/mark-selection.js'
import 'codemirror/addon/search/match-highlighter.js'
export default {
name: 'VueCode',
components: { codemirror },
props: {
cmTheme: {
type: String,
required: false,
default: 'default'
},
cmMode: {
type: String,
required: false,
default: ''
},
cmIndentUnit: {
type: Number,
required: false,
default: 2
},
autoFormatJson: {
type: Boolean,
required: false,
default: true
},
editorValue: {
type: String,
required: false,
default: '{}'
}
},
data() {
return {
cmOptions: {
theme: !this.cmTheme || this.cmTheme === 'default' ? 'default' : this.cmTheme, // 主题
mode: !this.cmMode || this.cmMode === 'default' ? 'application/json' : this.cmMode, // 代码格式
tabSize: 2, // tab的空格个数
indentUnit: !this.cmIndentUnit ? 2 : this.cmIndentUnit, // 一个块(编辑语言中的含义)应缩进多少个空格
autocorrect: true, // 自动更正
spellcheck: true, // 拼写检查
lint: true, // 检查格式
lineNumbers: true, // 是否显示行数
lineWrapping: true, // 是否自动换行
styleActiveLine: true, // line选择是是否高亮
keyMap: 'default', // sublime编辑器效果
matchBrackets: true, // 括号匹配
autoCloseBrackets: true, // 在键入时将自动关闭括号和引号
matchTags: { bothTags: true }, // 将突出显示光标周围的标签
foldGutter: true, // 可将对象折叠,与下面的gutters一起使用
gutters: [
'CodeMirror-lint-markers',
'CodeMirror-linenumbers',
'CodeMirror-foldgutter'
],
highlightSelectionMatches: {
minChars: 2,
style: 'matchhighlight',
showToken: true
}
},
enableAutoFormatJson: this.autoFormatJson == null ? true : this.autoFormatJson // json编辑模式下,输入框失去焦点时是否自动格式化,true 开启, false 关闭
}
},
created() {
try {
if (!this.editorValue) {
this.cmOptions.lint = false
return
}
if (this.cmOptions.mode === 'application/json') {
if (!this.enableAutoFormatJson) {
return
}
this.editorValue = this.formatStrInJson(this.editorValue)
}
} catch (e) {
console.log('初始化codemirror出错:' + e)
}
},
methods: {
resetLint() {
if (!this.$refs.myCm.codemirror.getValue()) {
this.$nextTick(() => {
this.$refs.myCm.codemirror.setOption('lint', false)
})
return
}
this.$refs.myCm.codemirror.setOption('lint', false)
this.$nextTick(() => {
this.$refs.myCm.codemirror.setOption('lint', true)
})
},
// 格式化字符串为json格式字符串
formatStrInJson(strValue) {
return JSON.stringify(
JSON.parse(strValue),
null,
this.cmIndentUnit
)
},
onCmCodeChanges(cm, changes) {
this.$emit('sendCode', cm.getValue())
this.resetLint()
},
// 失去焦点时处理函数
onCmBlur(cm, event) {
try {
const editorValue = cm.getValue()
if (this.cmOptions.mode === 'application/json' && editorValue) {
if (!this.enableAutoFormatJson) {
return
}
this.editorValue = this.formatStrInJson(editorValue)
}
} catch (e) {
// 啥也不做
}
},
// 按下键盘事件处理函数
onKeyDown(event) {
const keyCode = event.keyCode || event.which || event.charCode
const keyCombination =
event.ctrlKey || event.altKey || event.metaKey
if (!keyCombination && keyCode > 64 && keyCode < 123) {
this.$refs.myCm.codemirror.showHint({ completeSingle: false })
}
},
// 按下鼠标时事件处理函数
onMouseDown(event) {
this.$refs.myCm.codemirror.closeHint()
},
// 黏贴事件处理函数
OnPaste(event) {
if (this.cmOptions.mode === 'application/json') {
try {
this.editorValue = this.formatStrInJson(this.editorValue)
} catch (e) {
// 啥都不做
}
}
}
}
}
</script>
<style scoped>
.CodeMirror {
position: relative;
height: 100vh;
overflow: hidden;
margin-top: 10px;
}
</style>
<!-- <template>
<div class="exercise">
<codemirror
v-model="codeSnippets"
:options="cmOptions"
/>
</div>
</template>
<script>
import { codemirror } from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
export default {
components: {
codemirror
},
data() {
return {
cmOptions: {
tabSize: 4,
mode: 'text/javascript', // 模式
theme: 'base16-dark', // 主题
lineNumbers: true, // 是否显示行数
line: true,
viewportMargin: Infinity, // 处理高度自适应时搭配使用
highlightDifferences: true,
autofocus: false,
indentUnit: 2,
smartIndent: true,
readOnly: true, // 只读
showCursorWhenSelecting: true,
firstLineNumber: 1
// 更多配置查询 https://codemirror.net/doc/manual.html#config
},
codeSnippets:
`for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1)
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1)
}`
}
}
}
</script>
<style> /* 注意:这里的样式需要全局,如果写了scoped会导致样式不生效 */
.CodeMirror {
border: 1px solid #eee;
height: auto; /* 编辑器盒子高度自适应 */
width: 30%;
}
</style> -->
- 父组件:
数据在父组件中进行管理,子组件中填写代码之后需要给父组件传递参数
- 子组件初始化时的代码需要父组件传递的参数
<vueCode
ref="vueCode"
:cm-mode="cmMode"
:editor-value="form.yamlFile"
@sendCode="(value) => {
editorValue = value
form.yamlFile = value
}"
/>
import vueCode from './vueCodemirror'
// yarml代码的高亮
import 'codemirror/mode/yaml/yaml.js'
- 在vue中实现在线代码编辑器(lua) - ace/codemirror/monaco-editor
- 内容很完善的一篇文章- 另外一篇
基于 Vue + Codemirror 实现 SQL 在线编辑器