前言
適配 Vue3 的富文本插件不多,我看了很多插件官網,也有很多寫的非常棒的,有UI非常優雅讓人耳目一新的,也有功能非常全面的。
如:
- Quill,簡單易用,功能全面。
- editorjs,UI極其優雅,非常好看。
- ckeditor-5,一款完全重寫的富文本編輯器,支持現代 Web 標準,例如模塊化架構、原生語義化輸出等。
還有很多優秀的富文本編輯器插件,就不一一列舉了。
可惜這些都只有英文原文檔,對于我這樣英語閱讀能力不是很好的人來說,實在是一種煎熬,當然也是因為周期比較短,沒有時間去研究,所以選擇了這一款易上手的插件 wangEditor。
推薦原因有二:
- wangEditor 有詳細的中文文檔,以及中文交流環境。因為作者就是國內程序員。
- wangEditor 基于 slate 內核開發,但不依賴于 React ,所以它本身無框架依賴。
一、安裝
安裝 wangeditor 插件
npm install @wangeditor/editor --save
# yarn add @wangeditor/editor
安裝 Vue3 組件
npm install @wangeditor/editor-for-vue@next --save
# yarn add @wangeditor/editor-for-vue@next
二、使用
1. 簡單使用
這個組件使用起來非常簡單,如果只想簡單使用,按照下面的實例,即可實現:
<template><div style="border: 1px solid #ccc"><Toolbarstyle="border-bottom: 1px solid #ccc":editor="editorRef":defaultConfig="toolbarConfig":mode="mode"/><Editorstyle="height: 500px; overflow-y: hidden;"v-model="valueHtml":defaultConfig="editorConfig":mode="mode"@onCreated="handleCreated"/></div>
</template>
<script>
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { onBeforeUnmount, ref, shallowRef } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'export default {components: { Editor, Toolbar },setup() {// 編輯器實例,必須用 shallowRefconst editorRef = shallowRef()// 內容 HTMLconst valueHtml = ref('')const toolbarConfig = {}const editorConfig = { placeholder: '請輸入內容...' }// 組件銷毀時,也及時銷毀編輯器onBeforeUnmount(() => {const editor = editorRef.valueif (editor == null) returneditor.destroy()})const handleCreated = (editor) => {editorRef.value = editor // 記錄 editor 實例,重要!}return {editorRef,valueHtml,mode: 'default', // 或 'simple'toolbarConfig,editorConfig,handleCreated};}
}
</script>
以上,即可實現最簡單的富文本編輯功能,valueHtml
就是富文本編輯的內容,只需要使用 v-html
指令即可將其渲染。
2. 配置菜單欄
上面的實例很多功能不完善,只有最原始的功能,如果需要更加豐富的功能,需要對菜單欄進行自定義編輯。
<template><div class="edit"><Toolbar class="Toolbar" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" /><Editor class="Editor" :defaultConfig="editorConfig" :mode="mode" v-model="valueHtml" @onCreated="handleCreated" @customPaste="customPaste" /></div>
</template>
三、自定義圖片\視頻上傳功能
自帶圖片上傳功能文檔
自帶的圖片、視頻上傳服務可能無法 適用與真實的開發場景,所以對這一塊的功能進行自定義是必然的。
在同一頁面公共地方寫 editorConfig.MENU_CONF['uploadImage']
方法,上傳圖片、視頻時會自動觸發,可以同時選擇多張照片上傳,圖片會一張一張上傳。
// 自定義圖片上傳
editorConfig.MENU_CONF['uploadImage'] = {async customUpload(file, insertFn) {let formData = new FormData();formData.append('files', file);try {// 這里結合實際場景寫自己上傳圖片的邏輯,此處代碼僅為示例const { data } = await upload(formData);// 對圖片進行處理,同樣需要結合實際場景data.forEach(item => {insertFn(item, 'image', item)})} catch (error) {console.log(error);}}
}// 自定義視頻上傳
editorConfig.MENU_CONF['uploadVideo'] = {async customUpload(file, insertFn) {let formData = new FormData();formData.append('files', file);try {// 這里結合實際場景寫自己上傳圖片的邏輯,此處代碼僅為示例const { data } = await upload(formData);// 對圖片進行處理,同樣需要結合實際場景data.forEach(item => {insertFn(item, 'video')})} catch (error) {console.log(error);}}
}
注意
- 圖片無法控制具體寬度,只能按照比例確定寬度
- 圖片默認為自身100%寬度,如需限制,可以在盒子外層使用
!important
常見錯誤
vue-router.mjs:3471 Error: Module build failed (from ./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js): TypeError: Cannot read property 'content' of null
可能是vue-loader
版本有問題,較低或較高都有可能;也有可能是寫法有問題,建議仔細檢查代碼,這個問題在ts
中很容易出現。
四、復制粘貼功能
這個功能原本就有,默認會攜帶格式,如需去除,可以對齊進行修改和限制。以下示例為粘貼純文本,如果更多限制,可以自行改寫。
const customPaste = (editor, event, callback) => {const text = event.clipboardData.getData('text/plain') // 獲取粘貼的純文本if (text) {editor.insertText(text)event.preventDefault()callback(false)}
}
如需作者補充或修改,歡迎在評論區留言。
END