Vue使用codemirror實(shí)現(xiàn)一個(gè)可插入自定義標(biāo)簽的textarea
寫在開頭
本章來(lái)分享一個(gè)小案例,具體效果如上圖所示。
該案例主要通過(guò) CodeMirror
來(lái)實(shí)現(xiàn),而 CodeMirror
是一個(gè)通過(guò) JS
實(shí)現(xiàn)的Web代碼編輯器組件,它帶有大量的語(yǔ)言模式、CSS主題和很多高級(jí)的插件功能,還允許進(jìn)一步擴(kuò)展,總之它非常強(qiáng)大。
是一個(gè)很不錯(cuò)的產(chǎn)品,值得推薦入手。
本次小編使用的是 CodeMirror5
版本,最新版本已經(jīng)到 6
了,而且開發(fā)者們也在積極維護(hù)。
這兩個(gè)版本差別還是挺大的,不過(guò)呢,對(duì)本篇文案的案例影響卻不大,我們只是使用到了其中一個(gè)很小的功能,所以你想使用哪個(gè)版本都是可以的。
貼兩個(gè)版本的文檔地址,可以自己瞅瞅:
正文
接下來(lái)就開始進(jìn)入主題了。
安裝:
npm install codemirror@5.65.14
演示部分小編選擇使用 Vue
,其他技術(shù)棧都是可以的。
頁(yè)面結(jié)構(gòu):
<template> <div> <div class="textarea-editor"> <textarea ref="textarea" class="textarea" /> </div> <input v-model="content" placeholder="請(qǐng)輸入標(biāo)簽內(nèi)容" /> <button @click="addTag">添加</button> </div> </template>
JS
邏輯:
// 編輯器基本樣式 import "codemirror/lib/codemirror.css"; // 提示語(yǔ)樣式 import "codemirror/addon/display/placeholder"; import CodeMirror from "codemirror"; export default { data() { return { content: "", $cm: null, // 添加 $ 開頭能避免實(shí)例對(duì)象進(jìn)行依賴收集 }; }, mounted() { this.init(); }, methods: { /** @name 初始化 **/ init() { this.$cm = CodeMirror.fromTextArea(this.$refs.textarea, { placeholder: "請(qǐng)輸入......", lineWrapping: true, // 自動(dòng)換行 }); }, /** @name 標(biāo)記 **/ markVariable(mark) { // 創(chuàng)建自定義的標(biāo)簽元素 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; // 標(biāo)記特定的文本:https://codemirror.net/5/doc/manual.html#api_history this.$cm.markText(mark.start, mark.end, { replacedWith: spanDom, // 將特定位置的文本替換成給定的節(jié)點(diǎn)元素,必須是行元素,不能是塊元素 atomic: true, // 原子化,會(huì)把節(jié)點(diǎn)元素當(dāng)成一個(gè)整體,光標(biāo)不會(huì)進(jìn)入其中 }); }, /** @name 插入 **/ insertVariable(content) { if (!content) return; // 獲取自定義標(biāo)簽未插入之前的光標(biāo)對(duì)象,記錄了光標(biāo)的位置和狀態(tài) const cursor = this.$cm.getCursor(); // 將自定義標(biāo)簽插入textarea中:https://codemirror.net/5/doc/manual.html#api_selection // 在前后加上 ##與 $$ 只是方便我們后期getValue()的時(shí)候好進(jìn)行內(nèi)容匹配 this.$cm.replaceSelection(`##${content}$$`); // 將插入的自定義標(biāo)簽進(jìn)行標(biāo)記(將 ##${content}$$ 變成 <span>{content}</span>) this.markVariable({ start: cursor, end: this.$cm.getCursor(), // 獲取自定義標(biāo)簽插入之后的光標(biāo)對(duì)象 variable: content, }); this.$cm.setCursor(this.$cm.getCursor()); this.$cm.focus(); }, /** @name 添加自定義標(biāo)簽 **/ addTag() { this.insertVariable(this.content); }, /** @name 獲取值 **/ getValue() { const value = this.$cm.getValue(); console.log(value); }, }, };
Em......以上代碼小編都寫上了詳細(xì)的注釋,代碼也縮減到不能再縮啦,應(yīng)該不是很難,相信都能看懂啦。
可能需要注意的是 CodeMirror
的光標(biāo)對(duì)象:
CodeMirror
給我們提供了很多操作輸入內(nèi)容的方法,很多時(shí)候都需要我們提供這個(gè)光標(biāo)對(duì)象。
最后就是樣式啦:
<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>
以上就是這個(gè)案例的全部源碼內(nèi)容啦。
結(jié)尾
可能有小伙伴會(huì)在想做一個(gè)可插入自定義標(biāo)簽的 textarea
,需要那么麻煩專門去引入 CodeMirror
嗎?
當(dāng)然不需要,如果僅僅是這個(gè)功能的話
但是,由于小編業(yè)務(wù)中對(duì)這個(gè) textarea
還有很多其他需求,比如字體顏色的處理、智能提示、復(fù)制粘貼、兼容性問(wèn)題等等,所以選擇 CodeMirror
可以幫忙省下很多麻煩事。
到此這篇關(guān)于Vue使用codemirror實(shí)現(xiàn)一個(gè)可插入自定義標(biāo)簽的textarea的文章就介紹到這了,更多相關(guān)Vue codemirror實(shí)現(xiàn)自定義標(biāo)簽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VUE2實(shí)現(xiàn)事件驅(qū)動(dòng)彈窗示例
本篇文章主要介紹了VUE2實(shí)現(xiàn)事件驅(qū)動(dòng)彈窗示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10Vue集成three.js并加載glb、gltf、FBX、json模型的場(chǎng)景分析
這篇文章主要介紹了Vue集成three.js,并加載glb、gltf、FBX、json模型,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09vue2.0 + element UI 中 el-table 數(shù)據(jù)導(dǎo)出Excel的方法
下面小編就為大家分享一篇vue2.0 + element UI 中 el-table 數(shù)據(jù)導(dǎo)出Excel的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03Vue動(dòng)畫之第三方類庫(kù)實(shí)現(xiàn)動(dòng)畫方式
這篇文章主要介紹了Vue動(dòng)畫之第三方類庫(kù)實(shí)現(xiàn)動(dòng)畫方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04vue項(xiàng)目開發(fā)中setTimeout等定時(shí)器的管理問(wèn)題
這篇文章主要介紹了vue項(xiàng)目開發(fā)中setTimeout等定時(shí)器的管理問(wèn)題,需要的朋友可以參考下2018-09-09VuePress在build打包時(shí)window?document?is?not?defined問(wèn)題解決
這篇文章主要為大家介紹了VuePress在build打包時(shí)window?document?is?not?defined問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07