需求:eladmin-ui中使用Codemirror高亮显示代码,并实现form表单的双向绑定。
npm install vue-codemirror --save
在项目的main.js
中引入我们需要的vue-codemirror
import VueCodeMirror from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
Vue.use(VueCodeMirror)
这里我自定义了一个组件MyCodeMirror
,代码如下:
<template>
<div>
<codemirror v-model="newConfigFile" :options="options" />
</div>
</template>
<script>
import { codemirror } from 'vue-codemirror'
import 'codemirror/theme/ambiance.css'
require('codemirror/mode/javascript/javascript')
// 核心样式
import 'codemirror/lib/codemirror.css'
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/addon/selection/active-line'
// 引入主题后还需要在 options 中指定主题才会生效
import 'codemirror/theme/paraiso-light.css'
import 'codemirror/theme/paraiso-dark.css'
import 'codemirror/theme/rubyblue.css'
import 'codemirror/mode/python/python.js'
import 'codemirror/keymap/sublime'
import 'codemirror/mode/css/css'
import 'codemirror/theme/monokai.css'
import 'codemirror/mode/yaml/yaml.js'
import 'codemirror/mode/yaml-frontmatter/yaml-frontmatter.js'
import 'codemirror/mode/xml/xml.js'
import 'codemirror/mode/htmlmixed/htmlmixed.js'
import 'codemirror/theme/base16-light.css'
import 'codemirror/mode/properties/properties.js'
import 'codemirror/theme/eclipse.css'
export default {
components: { codemirror },
props: {
configFile: {
type: String,
required: true
}
},
data() {
return {
// 默认配置
options: {
tabSize: 2, // 缩进格式
mode: 'yaml',
theme: 'rubyblue',
lineNumbers: true, // 显示行号
line: true,
styleActiveLine: true, // 高亮选中行
matchBrackets: true, // 括号匹配
hintOptions: {
completeSingle: true // 当匹配只有一项的时候是否自动补全
}
}
}
},
computed: {
newConfigFile: {
get() {
return this.configFile
},
set(val) {
this.$emit('parseCMValue', val)
}
}
},
methods: {
onOptions(value) {
if (value === 1) { // text
this.options.mode = 'text/javascript'
this.options.theme = 'monokai'
} else if (value === 4) { // yaml
this.options.mode = 'yaml'
this.options.theme = 'rubyblue'
} else if (value === 3) { // xml
this.options.mode = 'xml'
this.options.theme = 'ambiance'
} else if (value === 2) { // json
this.options.mode = 'application/json'
this.options.theme = 'eclipse'
} else if (value === 5) { // html
this.options.mode = 'text/html'
this.options.theme = 'base16-light'
} else if (value === 6) { // Properties
this.options.mode = 'properties'
this.options.theme = 'ambiance'
}
}
}
}
</script>
<style scoped>
</style>
先在页面中注册自定义组件
import MyCodeMirror from '@/components/MyCodeMirror/index'
export default {
components: { MyCodeMirror }
}
这里的需求是根据不同的文件类型,显示不同的样式和主题
<el-form-item label="配置文件格式">
<el-radio-group v-model="form.configFileType" @change="onOptions">
<el-radio :label="1">TEXT</el-radio>
<el-radio :label="4">YAML</el-radio>
<el-radio :label="3">XML</el-radio>
<el-radio :label="2">JSON</el-radio>
<el-radio :label="5">HTML</el-radio>
<el-radio :label="6">Properties</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="配置文件">
<div style="width: 590px">
<MyCodeMirror ref="MyCM" :config-file="form.configFile" @parseCMValue="parseCMValue" />
</div>
</el-form-item>
主题和样式监听事件:onOptions
onOptions(value) {
this.$refs.MyCM.onOptions(value)
},
这里最主要的还是双向绑定提交表单的问题。在我们的页面中有这样的代码:
:config-file="form.configFile" @parseCMValue="parseCMValue"
在自定义组件中有定义的v-model代码:
<codemirror v-model="newConfigFile" :options="options" />
组件中以configFile
接受页面中的:config-file
。这里需要注意的是直接v-model绑定报错,如图,子组件中不能直接修改父组件传的prop,会报错
我们使用computed计算属性重新赋值;将接收的configFile
赋值父组件:v-model="newConfigFile"
。再以parseCMValue
赋值给子组件:@parseCMValue="parseCMValue"
computed: {
newConfigFile: {
get() {
return this.configFile
},
set(val) {
this.$emit('parseCMValue', val)
}
}
},
接下来就是将取到的parseCMValue
赋值到form表单的configFile属性:
parseCMValue(value) {
this.form.configFile = value
}
至此,我们的需求代码高亮及双向绑定就完成了。