Vue使用codemirror實現一個可插入自定義標簽的textarea
寫在開頭
本章來分享一個小案例,具體效果如上圖所示。
該案例主要通過 CodeMirror 來實現,而 CodeMirror 是一個通過 JS 實現的Web代碼編輯器組件,它帶有大量的語言模式、CSS主題和很多高級的插件功能,還允許進一步擴展,總之它非常強大。
是一個很不錯的產品,值得推薦入手。
本次小編使用的是 CodeMirror5 版本,最新版本已經到 6 了,而且開發(fā)者們也在積極維護。

這兩個版本差別還是挺大的,不過呢,對本篇文案的案例影響卻不大,我們只是使用到了其中一個很小的功能,所以你想使用哪個版本都是可以的。
貼兩個版本的文檔地址,可以自己瞅瞅:
正文
接下來就開始進入主題了。
安裝:
npm install codemirror@5.65.14
演示部分小編選擇使用 Vue,其他技術棧都是可以的。
頁面結構:
<template>
<div>
<div class="textarea-editor">
<textarea ref="textarea" class="textarea" />
</div>
<input v-model="content" placeholder="請輸入標簽內容" />
<button @click="addTag">添加</button>
</div>
</template>
JS 邏輯:
// 編輯器基本樣式
import "codemirror/lib/codemirror.css";
// 提示語樣式
import "codemirror/addon/display/placeholder";
import CodeMirror from "codemirror";
export default {
data() {
return {
content: "",
$cm: null, // 添加 $ 開頭能避免實例對象進行依賴收集
};
},
mounted() {
this.init();
},
methods: {
/** @name 初始化 **/
init() {
this.$cm = CodeMirror.fromTextArea(this.$refs.textarea, {
placeholder: "請輸入......",
lineWrapping: true, // 自動換行
});
},
/** @name 標記 **/
markVariable(mark) {
// 創(chuàng)建自定義的標簽元素
const spanDom = document.createElement("span");
const label = mark.variable;
spanDom.title = label;
spanDom.innerText = label;
spanDom.classList.add("textarea-tag");
spanDom.dataset.variable = mark.variable;
// 標記特定的文本:https://codemirror.net/5/doc/manual.html#api_history
this.$cm.markText(mark.start, mark.end, {
replacedWith: spanDom, // 將特定位置的文本替換成給定的節(jié)點元素,必須是行元素,不能是塊元素
atomic: true, // 原子化,會把節(jié)點元素當成一個整體,光標不會進入其中
});
},
/** @name 插入 **/
insertVariable(content) {
if (!content) return;
// 獲取自定義標簽未插入之前的光標對象,記錄了光標的位置和狀態(tài)
const cursor = this.$cm.getCursor();
// 將自定義標簽插入textarea中:https://codemirror.net/5/doc/manual.html#api_selection
// 在前后加上 ##與 $$ 只是方便我們后期getValue()的時候好進行內容匹配
this.$cm.replaceSelection(`##${content}$$`);
// 將插入的自定義標簽進行標記(將 ##${content}$$ 變成 <span>{content}</span>)
this.markVariable({
start: cursor,
end: this.$cm.getCursor(), // 獲取自定義標簽插入之后的光標對象
variable: content,
});
this.$cm.setCursor(this.$cm.getCursor());
this.$cm.focus();
},
/** @name 添加自定義標簽 **/
addTag() {
this.insertVariable(this.content);
},
/** @name 獲取值 **/
getValue() {
const value = this.$cm.getValue();
console.log(value);
},
},
};Em......以上代碼小編都寫上了詳細的注釋,代碼也縮減到不能再縮啦,應該不是很難,相信都能看懂啦。
可能需要注意的是 CodeMirror 的光標對象:

CodeMirror 給我們提供了很多操作輸入內容的方法,很多時候都需要我們提供這個光標對象。
最后就是樣式啦:
<style scoped>
.textarea-editor {
width: 300px;
height: 140px;
border: 1px solid rgb(234, 234, 234);
font-size: 14px;
overflow: hidden;
position: relative;
cursor: text;
margin-bottom: 10px;
}
.textarea-editor:hover {
border-color: #6c8dff;
}
.textarea {
width: 100%;
height: 100%;
border: none;
background-color: transparent;
}
</style>
<style>
/* 全局樣式,覆蓋codemirror一些基本樣式 */
.textarea-editor .CodeMirror {
width: 100%;
height: 100%;
}
.textarea-editor pre.CodeMirror-line,
.textarea-editor pre.CodeMirror-line-like {
line-height: 24px;
outline: none;
}
.textarea-tag {
width: fit-content;
height: 24px;
line-height: 24px;
text-align: center;
min-width: 60px;
max-width: 260px;
font-size: 12px;
border-radius: 11px;
color: #fff;
background-color: #fab30b;
box-sizing: border-box;
padding: 2px 6px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
</style>
以上就是這個案例的全部源碼內容啦。
結尾
可能有小伙伴會在想做一個可插入自定義標簽的 textarea ,需要那么麻煩專門去引入 CodeMirror 嗎?
當然不需要,如果僅僅是這個功能的話
但是,由于小編業(yè)務中對這個 textarea 還有很多其他需求,比如字體顏色的處理、智能提示、復制粘貼、兼容性問題等等,所以選擇 CodeMirror 可以幫忙省下很多麻煩事。


到此這篇關于Vue使用codemirror實現一個可插入自定義標簽的textarea的文章就介紹到這了,更多相關Vue codemirror實現自定義標簽內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue中關于element的el-image 圖片預覽功能增加一個下載按鈕(操作方法)
這篇文章主要介紹了vue中關于element的el-image 圖片預覽功能增加一個下載按鈕,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04
Vue2.0利用 v-model 實現組件props雙向綁定的優(yōu)美解決方案
本篇文章主要介紹了Vue2 利用 v-model 實現組件props雙向綁定的優(yōu)美解決方案,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03
Vue?使用?ElementUi?el-upload?手動上傳文件限制上傳文件類型大小同名等進行限制
個人在做文件上傳功能的時候,踩過不少的坑,特在此記錄下,本文介紹Vue使用?ElementUi?el-upload?手動上傳文件限制上傳文件類型大小同名等進行限制問題,感興趣的朋友一起看看吧2024-02-02
vue控制臺警告Runtime directive used on compon
這篇文章主要為大家介紹了vue控制臺警告Runtime directive used on component with non-element root node解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06

