vue3.0在线编辑器codemirror开发
待续…
·
使用codemirror封装codeEditor.vue组件
<template>
<div class="in-coder-panel">
<textarea ref="textarea" v-model="code"></textarea>
</div>
</template>
<script>
// 引入全局实例
import _CodeMirror from 'codemirror/lib/codemirror'
// 核心样式
import 'codemirror/lib/codemirror.css'
// 引入主题后还需要在 options 中指定主题才会生效
// 需要引入具体的语法高亮库才会有对应的语法高亮效果, 目前已动态引入
// import 'codemirror/theme/midnight.css'
// 主题样式
import 'codemirror/addon/hint/show-hint.css'
import { reactive, defineComponent, toRefs, getCurrentInstance, onMounted, onBeforeUnmount } from 'vue'
// codemirror 官方其实支持通过 /addon/mode/loadmode.js 和 /mode/meta.js 来实现动态加载对应语法高亮库
// 但 vue 貌似没有无法在实例初始化后再动态加载对应 JS ,所以此处才把对应的 JS 提前引入
import 'codemirror/mode/javascript/javascript.js'
const codemirrorThemList = []
const requireModules = require.context('codemirror/theme/', false, /\.css$/)
requireModules.keys().forEach(value => {
const newValue = value.replace(/^\.\//, '').replace(/\.css$/, '')
codemirrorThemList.push(newValue)
})
// 尝试获取全局实例
const CodeMirror = window.CodeMirror || _CodeMirror
let coder = null // 编辑器实例
export default defineComponent({
name: 'codeEditor',
props: {
value: {
type: String,
default: ''
},
scene: {
type: String,
default: 'look' // add: 新增; edit: 编辑; look: 查看
},
eventType: {
type: String,
default: 'blur' // 可用事件'change', 'blur'等等;具体参考codemirror文档
},
theme: {
type: String,
default: '3024-day' // 编辑器主题色
}
},
setup(props, { emit }) {
const { proxy } = getCurrentInstance()
const data = reactive({
code: props.value, // 内部真实的内容
// 默认配置
options: {
mode: 'javascript', // 不设置的话,默认使用第一个引用
// 缩进格式
tabSize: 2,
// 主题,对应主题库 JS 需要提前引入
theme: props.theme,
// 显示行号
lineNumbers: true,
readOnly: (props.scene === 'add' || props.scene === 'edit') ? false : 'nocursor' // true: 不可编辑 false: 可编辑 'nocursor' 失焦,不可编辑
},
// 初始化
initialize: () => {
// 初始化编辑器实例,传入需要被实例化的文本域对象和默认配置
coder = CodeMirror.fromTextArea(proxy.$refs.textarea, data.options)
// 此处也可使用'change'事件,不过每次书写的过程中都会触发,为了提高性能,故默认使用'blur'
coder.on(props.eventType, coder=> {
emit('update:value', coder.getValue())
})
},
// 动态引入语法高亮库
importThemDynamic: () => {
return new Promise(resolve => {
codemirrorThemList.forEach(value => {
if (props.theme === value) {
import(`codemirror/theme/${props.theme}.css`)
resolve()
}
})
})
}
})
onMounted(() => {
// console.log('value:', props.value)
data.importThemDynamic().then(()=>{
data.initialize()
})
})
onBeforeUnmount(()=> {
coder.off(props.eventType)
})
return {
...toRefs(data)
}
}
})
</script>
<style lang="scss"> // 此处不可使用"scoped"
.in-coder-panel{
flex-grow: 1;
display: flex;
position: relative;
.CodeMirror {
flex-grow: 1;
text-align: left !important;
z-index: 1;
.CodeMirror-code {
line-height: 19px;
}
}
}
</style>
在页面中使用codeEditor.vue
<template>
<codeEditor v-model:value="code" :scene="type" theme="3024-day"></codeEditor>
</template>
<script>
import { defineComponent, reactive, toRefs } from 'vue'
import codeEditor from '@/components/common/codeEditor.vue'
export default defineComponent({
components: {
codeEditor
},
props: {
type: {
type: String,
default: 'add'
}
}
setup (props) {
const data = reactive({
code: 'let a = 123'
})
return {
...toRefs(data),
...toRefs(props)
}
}
})
</script>
更多推荐
已为社区贡献1条内容
所有评论(0)