一、安裝
yarn add monaco-editor
或
npm install monaco-editor --save
二、使用
<div ref="editorContainer" style="height:100%;"></div>
import * as monaco from 'monaco-editor';
const editorContainer = ref<any>(null)
const editor = ref<any>(null)
onMounted(() => {
editor.value = monaco.editor.create(editorContainer.value,{
value: "test",
language:"javascript",
folding: true, // 是否折疊
foldingHighlight: true, // 折疊等高線
foldingStrategy: "indentation", // 折疊方式 auto | indentation
showFoldingControls: "always", // 是否一直顯示折疊 always | mouseover
disableLayerHinting: true, // 等寬優(yōu)化
emptySelectionClipboard: false, // 空選擇剪切板
selectionClipboard: false, // 選擇剪切板
automaticLayout: true, // 自動布局
codeLens: false, // 代碼鏡頭
scrollBeyondLastLine: false, // 滾動完最后一行后再滾動一屏幕
colorDecorators: true, // 顏色裝飾器
accessibilitySupport: "off", // 輔助功能支持 "auto" | "off" | "on"
lineNumbers: "on", // 行號 取值: "on" | "off" | "relative" | "interval" | function
lineNumbersMinChars: 5, // 行號最小字符 number
readOnly: false, //是否只讀 取值 true | false
})
})
三、自定義高亮
monaco.languages.register({ id: 'mylanguages' })
monaco.languages.setMonarchTokensProvider('mylanguages', {
ignoreCase: true, // 忽略大小寫
tokenizer: {
root:[
[/curl/, {token: "string.escape"}],
[/-X|-H|-d/, {token: "keyword"}],
[/POST|GET|DELETE|PATCH|PUT/, {token: "comment.doc"}],
],
}
})
root中為高亮規(guī)則。[/curl/, {token: “string.escape”}]:表示 ‘curl’ 的高亮顏色為粉色
高亮顏色參考:https://microsoft.github.io/monaco-editor/monarch.html
效果:
四、自定義提示
monaco.languages.registerHoverProvider('mylanguages', { // 光標移入提示功能
provideHover: function (model, position, token) {
const lineword = model.getLineContent(position.lineNumber) // 獲取光標懸停所在行的所有內(nèi)容
const word = model.getWordAtPosition(position)?.word // 獲取光標懸停的單詞
if (word === "name") {
return {
contents: [
{ value: `${word}` },
{
value: [
"這是name的一些介紹",
"這是name的一些介紹",
].join("\n\n"),
},
],
};
} else if(undefined !== word){
return {
contents: [
{ value: `${word}` },
{
value: [
lineword
].join("\n\n"),
},
],
}
}
},
});
效果:
五、完整代碼
1、父組件:HomeView.vue
父組件中傳給子組件所需的組件高度、初始內(nèi)容、高亮類型、是否只讀
子組件通過editorChange方法給父組件實時傳值
<template>
<div>
<monaco
ref="monacoEdit"
:value="data"
:readonly="false"
type="curl"
:height="300"
@editorChange="editorChange"
></monaco>
</div>
</template>
<script setup lang="ts">
import monaco from '../components/MonacoView.vue'
import { ref, toRefs, reactive } from "vue"
const data = ref('test')
function editorChange(val: string) {
//val:子組件實時傳過來的值
console.log(val)
}
</script>
<style scoped>
</style>
2、子組件:MonacoView.vue
<template>
<div class="editorapp">
<div ref="editorContainer" :style="{height:editor_height}"></div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, toRaw, watchEffect } from "vue"
// 引入方法一
import * as monaco from 'monaco-editor';
// 引入方法二( 這種引入方法體積小但沒有鼠標懸停方法registerHoverProvider)
// import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
// import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution'
const emit = defineEmits(['contentChange'])
const props = defineProps({
value: {
type: String,
default: '',
},
height: { // 編輯器height
type: [String, Number],
default: 500,
},
readonly: { // 是否只讀
type: Boolean,
default: false,
},
type: { // 高亮類型(javascript、curl等,javascript:自帶的,curl:自定義的高亮規(guī)則)
type: String,
default: 'javascript',
}
})
const editorContainer = ref<any>(null)
const editor = ref<any>(null)
const data = ref(props.value)
const editor_height = ref(`${props.height}px`)
onMounted(() => {
// 初始化編輯器,確保dom已經(jīng)渲染
if(props.type === 'curl'){ // 如果是curl 類型則重新定義高亮規(guī)則,否則使用自帶的高亮語言
monaco.languages.register({ id: props.type })
monaco.languages.setMonarchTokensProvider(props.type, {
ignoreCase: true,
tokenizer: {
root:[
[/curl/, {token: "string.escape"}],
[/-X|-H|-d/, {token: "keyword"}],
[/POST|GET|DELETE|PATCH|PUT/, {token: "comment.doc"}],
],
}
})
}
monaco.languages.registerHoverProvider(props.type, { // 光標移入提示功能
provideHover: function (model, position, token) {
const lineword = model.getLineContent(position.lineNumber) // 獲取光標懸停所在行的所有內(nèi)容
const word = model.getWordAtPosition(position)?.word // 獲取光標懸停的單詞
if (word === "name") {
return {
contents: [
{ value: `${word}` },
{
value: [
"這是name的一些介紹",
"這是name的一些介紹",
].join("\n\n"),
},
],
};
} else if(undefined !== word){
return {
contents: [
{ value: `${word}` },
{
value: [
lineword
].join("\n\n"),
},
],
}
}
},
});
editor.value = monaco.editor.create(editorContainer.value,{
value: data.value,
language:props.type,
folding: true, // 是否折疊
foldingHighlight: true, // 折疊等高線
foldingStrategy: "indentation", // 折疊方式 auto | indentation
showFoldingControls: "always", // 是否一直顯示折疊 always | mouseover
disableLayerHinting: true, // 等寬優(yōu)化
emptySelectionClipboard: false, // 空選擇剪切板
selectionClipboard: false, // 選擇剪切板
automaticLayout: true, // 自動布局
codeLens: false, // 代碼鏡頭
scrollBeyondLastLine: false, // 滾動完最后一行后再滾動一屏幕
colorDecorators: true, // 顏色裝飾器
accessibilitySupport: "off", // 輔助功能支持 "auto" | "off" | "on"
lineNumbers: "on", // 行號 取值: "on" | "off" | "relative" | "interval" | function
lineNumbersMinChars: 5, // 行號最小字符 number
readOnly: props.readonly, //是否只讀 取值 true | false
})
editor.value.onDidChangeModelContent((val: any) => {
//內(nèi)容改變時給父組件實時返回值
emit('editorChange', toRaw(editor.value).getValue())
})
})
watchEffect(()=>{ // 監(jiān)聽父組件值的變化,重新賦值給編輯器
if(editor.value)
toRaw(editor.value).setValue(props.value)
})
</script>
<style scoped>
.editorapp {
height: 100%;
width: 100vh;
}
</style>
效果:
六、實際問題
沒有實現(xiàn)雙向綁定。子組件給父組件傳值會比較麻煩,如果是很多頁面都要使用的話要重復寫很多接收參數(shù)的方法,并且重復定義很多額外的參數(shù)來接收子組件的傳值
父組件中定義額外的參數(shù)來接收子組件的傳值的原因:
修改:
父組件中:改為v-model,不再需要editorChange方法了文章來源:http://www.zghlxwxcb.cn/news/detail-602245.html
<monaco-editor ref="monacoEdit" v-model="data" :readonly="false" main="javascript" bgcolor="vs-dark'" />
子組件中:(只顯示修改的部分)文章來源地址http://www.zghlxwxcb.cn/news/detail-602245.html
// 編輯器避免重復賦值
watchEffect(() => {
if (editor.value && toRaw(editor.value).getValue() !== props.modelValue)
toRaw(editor.value).setValue(props.modelValue)
})
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()
// 監(jiān)聽值的變化
editor.value.onDidChangeModelContent((val: any) => {
// 給父組件實時返回最新文本
emit('update:modelValue', toRaw(editor.value).getValue())
})
到了這里,關(guān)于Monaco Editor安裝,vue3中使用,自定義高亮,自定義提示,附完整代碼的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!