codemirror 是一个非常强大的代码编辑器插件,但官方并没有提供 vue 的支持版本,不过跟 vue 集成的步骤并不复杂,以下是具体实现
更多精彩
- 更多技术博客,请移步 IT人才终生实训与职业进阶平台 - 实训在线
相关网址
- Vue 官方插件库推荐的集成实现
- 这个实现做的比较全面,但不支持动态语法高亮的切换
- codemirror 支持的语言类型
- codemirror 官网
实现效果
具体实现
- 首先需要运行
npm i codemirror --save
在项目中安装对应组件
<template><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>
</template><script type="text/ecmascript-6">// 引入全局实例import _CodeMirror from 'codemirror'// 核心样式import 'codemirror/lib/codemirror.css'// 引入主题后还需要在 options 中指定主题才会生效import 'codemirror/theme/cobalt.css'// 需要引入具体的语法高亮库才会有对应的语法高亮效果// codemirror 官方其实支持通过 /addon/mode/loadmode.js 和 /mode/meta.js 来实现动态加载对应语法高亮库// 但 vue 貌似没有无法在实例初始化后再动态加载对应 JS ,所以此处才把对应的 JS 提前引入import 'codemirror/mode/javascript/javascript.js'import 'codemirror/mode/css/css.js'import 'codemirror/mode/xml/xml.js'import 'codemirror/mode/clike/clike.js'import 'codemirror/mode/markdown/markdown.js'import 'codemirror/mode/python/python.js'import 'codemirror/mode/r/r.js'import 'codemirror/mode/shell/shell.js'import 'codemirror/mode/sql/sql.js'import 'codemirror/mode/swift/swift.js'import 'codemirror/mode/vue/vue.js'// 尝试获取全局实例const CodeMirror = window.CodeMirror || _CodeMirrorexport default {name: 'in-coder',props: {// 外部传入的内容,用于实现双向绑定value: String,// 外部传入的语法类型language: {type: String,default: null}},data () {return {// 内部真实的内容code: '',// 默认的语法类型mode: 'javascript',// 编辑器实例coder: null,// 默认配置options: {// 缩进格式tabSize: 2,// 主题,对应主题库 JS 需要提前引入theme: 'cobalt',// 显示行号lineNumbers: true,line: true},// 支持切换的语法高亮类型,对应 JS 已经提前引入// 使用的是 MIME-TYPE ,不过作为前缀的 text/ 在后面指定时写死了modes: [{value: 'css',label: 'CSS'}, {value: 'javascript',label: 'Javascript'}, {value: 'html',label: 'XML/HTML'}, {value: 'x-java',label: 'Java'}, {value: 'x-objectivec',label: 'Objective-C'}, {value: 'x-python',label: 'Python'}, {value: 'x-rsrc',label: 'R'}, {value: 'x-sh',label: 'Shell'}, {value: 'x-sql',label: 'SQL'}, {value: 'x-swift',label: 'Swift'}, {value: 'x-vue',label: 'Vue'}, {value: 'markdown',label: 'Markdown'}]}},mounted () {// 初始化this._initialize()},methods: {// 初始化_initialize () {// 初始化编辑器实例,传入需要被实例化的文本域对象和默认配置this.coder = CodeMirror.fromTextArea(this.$refs.textarea, this.options)// 编辑器赋值this.coder.setValue(this.value || this.code)// 支持双向绑定this.coder.on('change', (coder) => {this.code = coder.getValue()if (this.$emit) {this.$emit('input', this.code)}})// 尝试从父容器获取语法类型if (this.language) {// 获取具体的语法类型对象let modeObj = this._getLanguage(this.language)// 判断父容器传入的语法是否被支持if (modeObj) {this.mode = modeObj.label}}},// 获取当前语法类型_getLanguage (language) {// 在支持的语法类型列表中寻找传入的语法类型return this.modes.find((mode) => {// 所有的值都忽略大小写,方便比较let currentLanguage = language.toLowerCase()let currentLabel = mode.label.toLowerCase()let currentValue = mode.value.toLowerCase()// 由于真实值可能不规范,例如 java 的真实值是 x-java ,所以讲 value 和 label 同时和传入语法进行比较return currentLabel === currentLanguage || currentValue === currentLanguage})},// 更改模式changeMode (val) {// 修改编辑器的语法配置this.coder.setOption('mode', `text/${val}`)// 获取修改后的语法let label = this._getLanguage(val).label.toLowerCase()// 允许父容器通过以下函数监听当前的语法值this.$emit('language-change', label)}}}
</script><style lang="stylus" rel="stylesheet/stylus">.in-coder-panelflex-grow 1display flexposition relative.CodeMirrorflex-grow 1z-index 1.CodeMirror-codeline-height 19px.code-mode-selectposition absolutez-index 2right 10pxtop 10pxmax-width 130px
</style>
---------------------
作者:asing1elife
来源:CSDN
原文:https://blog.csdn.net/asing1elife/article/details/89249154
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件