codemirror6實現(xiàn)在線代碼編輯器使用詳解
背景
最近在升級一個老項目,其中涉及將codemirror5遷移到codemirror6,本文特意記錄一下codemirror6的學習及升級過程~
介紹
CodeMirror是Web的代碼編輯器組件。它可以在網(wǎng)站中用于實現(xiàn)文本輸入字段,并支持許多編輯功能,并具有豐富的編程接口以允許進一步擴展。
codemirror5、codemirror6對比
其實codemirror
官網(wǎng)中的遷移指南有詳細列舉兩個版本關(guān)鍵特性的一些對比,下面列舉一些實際項目中用到的特性對比:
對比項 | codemirror5 | codemirror6 |
---|---|---|
創(chuàng)建編輯器 | codemirror.fromTextarea(element) | import { basicSetup, EditorState, EditorView } from '@codemirror/basic-setup'; const editor = new EditorView({state:EditorState.create( {doc: code,extensions: [basicSetup]}), parent: this.$refs.editor as HTMLDivElement,}); |
設(shè)置值 | cm.setValue(text) | ①更改值:cm.dispatch({changes: {from: 0, to:cm.state.doc.length, insert: text}}) ②替換整個狀態(tài):cm.setState(EditorState.create({doc: text, extensions: ...})) |
取值 | cm.getValue() | cm.state.doc.toString() |
codemirror6 核心包
由上表的對比也可以看出,codemirror6創(chuàng)建編輯器需要靠自己組裝,組裝部分并不難,但必須安裝并導(dǎo)入所需的組件。以下是核心包,沒有它們就很難設(shè)置一個編輯器,它們是:
- @codemirror/state,它定義了表示編輯器狀態(tài)和對該狀態(tài)的更改的數(shù)據(jù)結(jié)構(gòu)。
- @codemirror/view,這是一個顯示組件,它知道如何向用戶顯示編輯器狀態(tài),并將基本的編輯操作轉(zhuǎn)換為狀態(tài)更新。
- @codemirror/commands定義了很多編輯命令和一些鍵綁定。
舉個栗子,我們可以看官網(wǎng)對于最輕量的編輯器的示例:
import {EditorState} from "@codemirror/state" import {EditorView, keymap} from "@codemirror/view" import {defaultKeymap} from "@codemirror/commands" let startState = EditorState.create({ // 顯示文本 doc: "Hello World", // 擴展,**keymap:** 配置要使用的快捷鍵;語言包等也是作為擴展在此配置 extensions: [keymap.of(defaultKeymap)] }) let view = new EditorView({ // 狀態(tài) state: startState, // 綁定元素 parent: document.body })
vue3+codemirror6實現(xiàn)簡易在線代碼編輯器
安裝依賴
// 安裝codemirror npm i codemirror // 這里語言包要自行安裝 npm i @codemirror/lang-javascript
創(chuàng)建編輯器
<template> <div ref="editorRef" class="editor-main"></div> </template> <script lang="ts" setup> import { basicSetup, EditorView } from "codemirror"; import { EditorState } from "@codemirror/state"; import { javascript } from "@codemirror/lang-javascript"; import {json} from '@codemirror/lang-json' import { onMounted, ref } from "vue"; const editorRef = ref(); const editorView = ref(); const initEditor = () => { if (typeof editorView.value !== "undefined") { editorView.value.destroy(); } const jsonString = `{ root: true, extends: [ "plugin:vue/vue3-essential", "eslint:recommended", "@vue/eslint-config-typescript", "@vue/eslint-config-prettier", "vue-global-api" ], parserOptions: { ecmaVersion: "latest", }, rules: { "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", endOfLine: "auto", "prettier/prettier": ["error", { "endOfLine": "auto" }] }, }` const startState = EditorState.create({ doc:jsonString, extensions: [basicSetup, javascript(),json()], }); if (editorRef.value) { editorView.value = new EditorView({ state: startState, parent: editorRef.value, }); } }; // onMounted生命周期可以保證讀取到dom元素 onMounted(() => { initEditor(); }); </script> <style lang="scss" scoped> .editor-main{ width: 100vw; height: 100vh; } </style>
這里的basicSetup擴展包含了行號,不需要再做額外的配置~
效果截圖
主題
codemirror6目前提供了theme-one-dark
主題,也可以使用theme進行拓展
// 安裝 npm i @codemirror/theme-one-dark // 使用 import { oneDarkTheme } from "@codemirror/theme-one-dark"; const startState = EditorState.create({ doc: jsonString, extensions: [basicSetup,oneDarkTheme, javascript(), json()], }); // 自定義主題 const myTheme = EditorView.theme({ "&": { color: "white", backgroundColor: "#034" }, ".cm-content": { caretColor: "#0e9" }, "&.cm-focused .cm-cursor": { borderLeftColor: "#0e9" }, "&.cm-focused .cm-selectionBackground, ::selection": { backgroundColor: "#074" }, ".cm-gutters": { backgroundColor: "#045", color: "#ddd", border: "none" } }, {dark: true}) // 使用 const startState = EditorState.create({ doc: jsonString, extensions: [basicSetup,myTheme, javascript(), json()], });
主題效果截圖:
獲取、更改編輯器的值
從兩個版本對比中也可以知道,codemirror6值的操作主要是對state的操作,數(shù)據(jù)流的互動如下圖所示,即該視圖聆聽事件。當DOM事件進來時,它(或綁定到密鑰的命令或按擴展名注冊的事件處理程序)將其轉(zhuǎn)換為狀態(tài)交易并分配它們。這建立了一個新狀態(tài)。當將新狀態(tài)授予視圖時,它將自行更新。
const undateValue = ()=>{ const value = editorView.value.state.doc.toString() if(value){ // 具體邏輯根據(jù)自己業(yè)務(wù)場景做變化 editorView.value.dispatch({changes: {from: 0, to:editorView.value.state.doc.length, insert: 'test'}}) } }
總結(jié)
至此,codemirror6的實踐算告一段落,當然還有很多復(fù)雜的功能可以拓展,感興趣的小伙伴也可以閱讀官方文檔進行實踐,雖然codemirror6的寫法跟5的有很大差異,需要自行組裝,但codemirror6的好處也顯而易見,減少重復(fù)代碼引入的同時可定制性也更強!
以上就是codemirror6實現(xiàn)在線代碼編輯器使用詳解的詳細內(nèi)容,更多關(guān)于codemirror 代碼編輯器的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript使用JSON.stringify()方法帶參及不帶參示例詳解
這篇文章主要介紹了JavaScript使用JSON.stringify()方法帶參及不帶參示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07Svelte調(diào)試模式j(luò)s級別差異和細化后的體積差異詳解
這篇文章主要為大家介紹了Svelte調(diào)試模式j(luò)s級別差異和細化后的體積差異詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12JavaScript國際化API格式化數(shù)據(jù)Intl.NumberFormat使用講解
這篇文章主要為大家介紹了JavaScript國際化API格式化數(shù)據(jù)Intl.NumberFormat使用講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06JavaScript?CSS優(yōu)雅實現(xiàn)網(wǎng)頁多主題風格換膚功能詳解
這篇文章主要為大家介紹了JavaScript?CSS優(yōu)雅的實現(xiàn)網(wǎng)頁多主題風格換膚功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02