概述
1.codemirror插件
相关网址
- Vue 官方插件库推荐的集成实现
- 这个实现做的比较全面,但不支持动态语法高亮的切换
- codemirror 支持的语言类型
- codemirror 官网
参考文章:
vue-codemirror 代码编辑器 - 简书
2.vue-codemirror插件
相关网址
1.vue-codemirror - npm
参考文章:
Vue(27)vue-codemirror实现在线代码编译器 _ - 腾讯云开发者社区-腾讯云
vue案例代码:
<!--这是文档界面-->
<template>
<div class="containner">
<!-- 左边导航区 -->
<div class="nav">
<!-- 头部搜索区 -->
<div class="nav_top">
<div class="input">
<el-input v-model="inputSeach" placeholder="请输入内容"></el-input>
</div>
<div class="img_seach">
<img
src="../../assets/img/seach.png"
@click="inputSeachClick"
alt=""
/>
</div>
</div>
<!-- 底部导航区 -->
<div class="nav_main">
<el-menu
:default-active="$route.hash"
class="el-menu-vertical-demo"
background-color="#181a1b"
text-color="#fff"
@open="showPage"
active-text-color="#ffd04b"
@select="handleSelect"
router
>
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>入门示例</span>
</template>
<el-menu-item index="#1">场景初始化</el-menu-item>
<el-menu-item index="#2">数据挂接</el-menu-item>
<el-menu-item index="#3">组件高亮</el-menu-item>
<el-menu-item index="#4">光源控制</el-menu-item>
<el-menu-item index="#5">交互控制</el-menu-item>
<el-menu-item index="#6">测量相关</el-menu-item>
</el-submenu>
<!-- 导航2 -->
<el-submenu index="2">
<template slot="title">
<i class="el-icon-location"></i>
<span>待开发</span>
</template>
<el-menu-item index="#0">选项1</el-menu-item>
</el-submenu>
</el-menu>
</div>
</div>
<!-- 右边 -->
<div class="wrap">
<!-- 代码区域编辑器 -->
<split-pane
split="vertical"
@resize="resize"
:min-percent="5"
:default-percent="25"
>
<template slot="paneL">
<split-pane split="horizontal" :min-percent="5">
<template slot="paneL">
<div>
<!-- 编辑器头部按钮 -->
<div class="btns">
<el-button type="primary" size="mini" @click="submitHtml"
>运行</el-button
>
<el-button type="primary" size="mini" @click="submitBack"
>重置</el-button
>
</div>
<!-- 编辑器 -->
<div class="edit">
<codemirror
class="code"
v-model="code"
:options="cmOptions"
></codemirror>
</div>
<!-- <pre class="pre">{{ code }}</pre> -->
</div>
</template>
<template slot="paneR">
<div class="doc">
<component :is="currentView"></component>
</div>
</template>
</split-pane>
</template>
<!-- 内嵌网页区域 -->
<template slot="paneR">
<div id="iframewrapper"></div>
</template>
</split-pane>
</div>
</div>
</template>
<script>
// import 《组件名称》 from '《组件路径》';
// 引入的插件部分
import { codemirror } from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
import 'codemirror/keymap/sublime' // sublime编辑器效果
import 'codemirror/theme/dracula.css'// 配置里面也需要theme设置为monokai
import 'codemirror/mode/vue/vue.js' // 配置里面也需要mode设置为vue
import 'codemirror/addon/selection/active-line' // 光标行背景高亮,配置里面也需要styleActiveLine设置为true
import dedent from 'dedent'
// 文档引入部分
import index_1_2 from '../apiShow/index_1_2.vue'
import index_1_3 from '../apiShow/index_1_3.vue'
import { log } from 'three'
export default {
// import引入的组件需要注入到对象中才能使用
components: { codemirror, index_1_2, index_1_3 },
data () {
// 这里存放数据
return {
code: '',
cmOptions: {
tabSize: 4, // tab的空格个数
theme: 'dracula', // 主题样式
lineWrapping: true, // 是否自动换行
styleActiveLine: true, // line选择是是否加亮
matchBrackets: true, // 括号匹配
mode: 'vue', // 实现javascript代码高亮
readOnly: false, // 只读
scrollbarStyle: 'native',
},
// 模糊搜索内容
inputSeach: '',
// 文档引入
index_1_2: index_1_2,
index_1_3: index_1_3,
}
},
// 监听属性 类似于data概念
computed: {
currentView: function () {
// if (this.$route.hash === '#1') {
// return this.index_1_2
// }
if (this.$route.hash === '#2') {
return this.index_1_3
} else {
return this.index_1_2
}
return false
}
},
// 监控data中的数据变化
watch: {},
// 方法集合
methods: {
resize () { },
// 保存
submitHtml () {
let text = this.code
const patternHtml = /<html[^>]*>((.|[nr])*)</html>/im
const patternHead = /<head[^>]*>((.|[nr])*)</head>/im
const arrayMatchesHead = patternHead.exec(text)
const patternBody = /<body[^>]*>((.|[nr])*)</body>/im
const arrayMatchesBody = patternBody.exec(text)
if (arrayMatchesHead) {
text = text.replace('<head>', '<head>')
} else if (patternHtml) {
text = text.replace('<html>', '<head>' + '</head>')
} else if (arrayMatchesBody) {
text = text.replace('<body>', '<body>')
}
// 动态创建iframe
const ifr = document.createElement('iframe')
ifr.setAttribute('frameborder', '0')
ifr.setAttribute('id', 'iframeResult')
ifr.setAttribute('height', '100%')
ifr.setAttribute('width', '100%')
// 把创建的iframe追加到页面中
document.getElementById('iframewrapper').innerHTML = ''
document.getElementById('iframewrapper').appendChild(ifr)
// 创建标签
const style = document.createElement('style')
style.innerHTML = '::-webkit-scrollbar {width: 2px;background-color: red;color: red;}'
ifr.contentWindow.document.getElementsByTagName('head')[0].appendChild(style)
const ifrw = (ifr.contentWindow) ? ifr.contentWindow : (ifr.contentDocument.document) ? ifr.contentDocument.document : ifr.contentDocument
// 打开一个新的文档
ifrw.document.open()
// 编写文档
ifrw.document.write(text)
// 关闭文档操作
ifrw.document.close()
},
submitCode (item) {
if (item == 1) {
this.code = dedent`
<!DOCTYPE html>
<html lang="en">
</html>
`
} else if (item == 2) {
this.code = dedent`
<!DOCTYPE html>
<html lang="en">
<body>
${'</script>'}
</body>
</html>
`
} else if (item == 3) {
this.code = dedent`
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
${'</script>'}
</body>
</html>
`
} else if (item == 4) {
this.code = dedent`
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<script type="module">
${'</script>'}
</body>
</html>
`
} else if (item == 5) {
this.code = dedent`
<!DOCTYPE html>
<html lang="en">
</html>
`
} else if (item == 6) {
this.code = dedent`
<!DOCTYPE html>
<html lang="en">
</html>
`
} else {
this.code = null;
}
this.submitHtml()
},
// 刷新
submitBack () {
// 根据刷新的地址请求html文本
// 点击刷新,拿到当前hash,并去除井号
const path = this.$route.hash.slice(1)
this.submitCode(path);
},
// 模糊搜索
inputSeachClick () {
// 无输入停止
if (this.inputSeach.length === 0) {
return false
}
},
// 打开就拿到key值
showPage (key) {
},
getMutilines (data) {
let content = new String(data);
let start = content.indexOf('/*') + 3;
let stop = content.lastIndexOf('*/');
return content.substring(start, stop);
},
// 当选中的选项不同时,展示不同的内容,key子选项卡index的值,keyPath [复选项卡的index,子选项卡的index]
handleSelect (key, keyPath) {
// 如果key的值为空或者未定义 停止向下执行
if (key === 'undefined' || key === '') return false
this.submitCode(key.slice(1));
}
},
getCode (id) {
},
// 生命周期 - 创建完成(可以访问当前this实例)
created () {
// 监听hash的变化
const _this = this
window.addEventListener('hashchange', function () {
_this.submitBack()
}, false)
},
// 生命周期 - 挂载完成(可以访问DOM元素)
mounted () {
// 当页面渲染完成后加载
this.$nextTick(function () {
// 点击时,刷新展示最开始展示的文档
this.submitBack()
})
},
beforeCreate () { }, // 生命周期 - 创建之前
beforeMount () { }, // 生命周期 - 挂载之前
beforeUpdate () { }, // 生命周期 - 更新之前
updated () { }, // 生命周期 - 更新之后
beforeDestroy () { }, // 生命周期 - 销毁之前
destroyed () { }, // 生命周期 - 销毁完成
activated () { } // 如果页面有keep-alive缓存功能,这个函数会触发
}
</script>
<style lang='less' scoped>
//@import url(); 引入公共css类
.containner {
display: flex;
box-sizing: border-box;
position: absolute;
padding-top: 77px;
width: 100%;
height: 100%;
min-width: 1600px;
background-color: #181a1b;
// border: 1px solid white;
.nav {
height: 100%;
min-width: 240px;
background-color: #181a1b;
.el-menu {
border: none;
}
/deep/.el-submenu__title {
border-radius: 10px;
margin: 10px;
// border-bottom: 1px solid rgba(204, 204, 204, 0.7);
}
.nav_top {
height: 30px;
width: 85%;
background-color: #3a3b3c;
border-radius: 10px;
display: flex;
margin: 0 auto;
margin-top: 2px;
.input {
width: 80%;
z-index: 9999;
/deep/.el-input__inner {
height: 30px;
padding: 0 10px;
color: rgb(235, 235, 235);
border: none;
background-color: rgba(143, 143, 143, 0);
}
}
.img_seach {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
img {
width: 18px;
height: 18px;
display: block;
}
}
}
}
/deep/.el-input__inner {
border-radius: 0% !important;
}
.el-menu-item.is-active {
background-color: #8d8d8d1a !important;
border-radius: 20px;
}
// 编辑器部分
.wrap {
box-sizing: border-box;
height: 100%;
flex: 1;
.top {
height: 25px;
width: 100%;
}
/deep/.splitter-pane-resizer {
background-color: #959595;
// opacity: 0.5;
}
.doc {
box-sizing: border-box;
width: 100%;
height: 100%;
// background-color: #181a1b6c;
background: linear-gradient(
to left,
rgba(0, 0, 0, 0.247),
#181a1bd3,
#181a1b
) !important;
backdrop-filter: saturate(180%) blur(20px);
color: rgb(56, 56, 56);
padding: 15px;
// 火狐隐藏滚动条
overflow-y: scroll;
scrollbar-color: transparent transparent;
scrollbar-track-color: transparent;
-ms-scrollbar-track-color: transparent;
}
}
/deep/ .CodeMirror-code {
margin: 10px;
margin-top: 20px;
margin-bottom: 500px;
margin-left: 0;
}
/deep/ .el-menu-item {
margin: 10px;
border-radius: 20px;
}
/deep/.CodeMirror-lines {
padding-left: 10px;
}
.btns {
box-sizing: border-box;
width: 100%;
height: 36px;
display: flex;
justify-content: center;
// background-color: #fff;
// border-left: 1px solid #ccc;
.el-button {
width: 100%;
height: 30px;
border-radius: 10px;
padding: 0;
margin: 2px 20px;
text-align: center;
line-height: 20px;
z-index: 9999;
}
.el-button--primary {
background-color: #242526;
border-color: #242526;
}
}
.el-button--primary:hover {
background-color: #4d4f52;
border-color: #4d4f52;
}
.edit {
height: 100%;
box-sizing: border-box;
.code {
box-sizing: border-box;
height: 800px;
width: 100%;
}
}
}
#iframewrapper {
width: 98%;
height: 99%;
// min-width: 1300px;
margin: 10px;
margin-top: 0;
box-sizing: border-box;
border-radius: 20px;
// border: 1px solid rgba(204, 204, 204, 0.7);
background-color: #242526;
}
</style>
// 全局样式
<style>
.CodeMirror {
box-sizing: border-box;
height: 100%;
overflow-y: scroll;
margin-top: 10px;
margin-left: 10px;
margin-right: 10px;
border-radius: 10px;
scrollbar-color: transparent transparent;
scrollbar-track-color: transparent;
-ms-scrollbar-track-color: transparent;
}
</style>
最后
以上就是欣喜火龙果为你收集整理的前端——代码编辑器1.codemirror插件2.vue-codemirror插件的全部内容,希望文章能够帮你解决前端——代码编辑器1.codemirror插件2.vue-codemirror插件所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复