1.簡介 開源 Web 富文本編輯器,開箱即用,配置簡單。一個產品的價值,就在於解決用戶的問題,提高效率、降低成本、增加穩定性和擴展性。wangEditor 不是為了做而做,也不是單純的模仿誰,而是經過上述問題分析之後,給出一個系統的解決方案。旨在真正去解決用戶的問題,產出自己的價值。更多資料見官網 ...
1.簡介
開源 Web 富文本編輯器,開箱即用,配置簡單。一個產品的價值,就在於解決用戶的問題,提高效率、降低成本、增加穩定性和擴展性。wangEditor 不是為了做而做,也不是單純的模仿誰,而是經過上述問題分析之後,給出一個系統的解決方案。旨在真正去解決用戶的問題,產出自己的價值。更多資料見官網地址:https://www.wangeditor.com/。
2.安裝
安裝 editor
yarn add @wangeditor/editor # 或者 npm install @wangeditor/editor --save
安裝 React 組件(可選)
yarn add @wangeditor/editor-for-react # 或者 npm install @wangeditor/editor-for-react --save
安裝 Vue2 組件(可選)
yarn add @wangeditor/editor-for-vue # 或者 npm install @wangeditor/editor-for-vue --save
安裝 Vue3 組件(可選)
yarn add @wangeditor/editor-for-vue@next # 或者 npm install @wangeditor/editor-for-vue@next --save
CDN
<!-- 引入 css --> <link href="https://unpkg.com/@wangeditor/editor@latest/dist/css/style.css" rel="stylesheet"> <!-- 引入 js --> <script src="https://unpkg.com/@wangeditor/editor@latest/dist/index.js"></script> <script> var E = window.wangEditor; // 全局變數 </script>
3.封裝代碼
./index.vue
1 <template> 2 <div class="v-rich-text"> 3 <div v-if="isSplitTool" :id="toolId" class="toolbar-container"></div> 4 <div v-if="isSplitTool" :id="textId" class="text-container"></div> 5 <div v-if="!isSplitTool" :id="textId"></div> 6 </div> 7 </template> 8 9 <script lang="ts"> 10 import { onMounted, onBeforeUnmount, ref, toRefs, watch } from "vue"; 11 import WangEditor from "wangeditor"; 12 import { basicProps } from "./props"; 13 14 export default { 15 name: "VRichText", 16 props: basicProps, 17 emits: ["change", "update:content"], 18 setup(props, { emit }) { 19 const { toolId, textId, content, isSplitTool } = toRefs(props); 20 let instance: any; 21 const textContent = ref(content.value); 22 23 watch( 24 () => props.content, 25 (nv) => { 26 if (nv !== instance.txt.html()) { 27 instance.txt.html(nv); 28 textContent.value = nv; 29 } 30 } 31 ); 32 33 onMounted(() => { 34 if (isSplitTool.value) { 35 instance = new WangEditor("#" + toolId.value, "#" + textId.value); 36 } else { 37 instance = new WangEditor("#" + textId.value); 38 } 39 Object.assign(instance.config, { 40 uploadImgShowBase64: true, 41 showFullScreen: false, 42 zIndex: 100, 43 focus: false, 44 onchange() { 45 emit("update:content", instance.txt.html()); 46 emit("change", instance.txt.html()); 47 }, 48 49 onBeforeUnmount(() => { 50 instance.destroy(); 51 instance = null; 52 }); 53 54 return { 55 toolId, 56 textId, 57 textContent, 58 isSplitTool, 59 }; 60 }, 61 }; 62 </script> 63 64 <style lang="scss" scoped> 65 .v-rich-text { 66 height: 100%; 67 display: flex; 68 flex-direction: column; 69 70 .text-container { 71 flex: 1; 72 height: 0; 73 } 74 } 75 </style> 76
./props.ts
1 export const basicProps = { 2 // 工具欄ID 3 toolId: { 4 type: String, 5 default: "toolbar-container", 6 }, 7 // 內容ID 8 textId: { 9 type: String, 10 default: "text-container", 11 }, 12 // 富文本內容 13 content: String, 14 // 是否拆分tool欄 15 isSplitTool: { 16 type: Boolean, 17 default: true, 18 }, 19 };
4.組件展示