vue 後臺管理系統富文本組件(四)UEditor(集成 135 編輯器插件)
簡介
135 編輯器應用於微信文章、企業網站、以及論壇等多種平臺,支持秒刷、一鍵排版、全文配色、公衆號管理、微信變量回復、48 小時羣發、定時羣發、雲端草稿、文本校對等 40 多項功能與服務, 像拼積木一樣組合排版的文章。 135 編輯器因其簡單的操作,強大的功能和美觀的排版深受廣大用戶喜愛。135 編輯器本質是基於百度 UEditor 二次開發的,因公司業務需求開發了本文組件。
準備工作
-
下載 UEditor
UEditor 官網下載鏈接 如圖下載開發版 1.4.3.3 完整源碼-點擊下載
下載完成後的目錄如下
其中好多文件目錄我們並不需要,如下只保留這些文件。editor_api.js
文件來自_examples
文件夾,_examples
文件夾刪除前把這個文件提取出來。
-
基於
vue-cli 3
搭建項目,主要依賴說明 (先安裝,scss和element-ui先配置,步驟略){ "axios": "^0.19.0", "core-js": "^3.4.4", "element-ui": "^2.13.0", "vue": "^2.6.10", "vue-router": "^3.1.3", "vuex": "^3.1.2" }
-
vue.config.js
配置如下,(assetsDir
是static
,publicPath
是"./"
)module.exports = { publicPath: "./", outputDir: "dist", assetsDir: "static", productionSourceMap: false, lintOnSave: true, devServer: { port: 8080, open: true, overlay: { warnings: true, errors: true } } };
VueRouter
的模式改成hash
模式const router = new VueRouter({ mode: 'hash', base: process.env.BASE_URL, routes })
-
然後在
public
裏新建文件夾static
把下載的ueditor
文件夾整個拿過來,放到static
目錄下 -
修改
editor_api.js
文件裏的baseURL
變量baseURL = '../_src/'
改爲baseURL = 'static/ueditor/_src/'
-
添加 135 插件,添加 135 插件文檔
a. 下載
http://www.135editor.com/js/ueditor/plugins/135editor.jshttp://www.135editor.com/js/ueditor/dialogs/135editor/135EditorDialogPage.html
b.放置文件
135editor.js
文件放到public/static/ueditor/_src/plugins
文件夾下135EditorDialogPage.html
文件放到public/static/ueditor/dialogs/135editor
文件夾下 沒有135editor
文件夾需要新建)c. 修改配置文件
在 ueditor.config.js 中 toolbars 項裏增加一個 135editor 菜單項toolbars: [ ['135editor', 'fullscreen', 'source', '|', 'undo', redo', .... ]]
d.添加 css (在後文 src/components/UEditor/index.vue 文件裏添加)
.edui-button.edui-for-135editor .edui-button-wrap .edui-button-body .edui-icon { background-image: url("http://static.135editor.com/img/icons/editor-135-icon.png") !important; background-size: 85%; background-position: center; background-repeat: no-repeat; }
-
public/index.html 裏添加文件 ueditor.config.js,editor_api.js,zh-cn.js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <title>135</title> </head> <body> <noscript> <strong >We're sorry but 135 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong > </noscript> <div id="app"></div> <!-- built files will be auto injected --> <!-- ueditor --> <script type="text/javascript" src="static/ueditor/ueditor.config.js" ></script> <script type="text/javascript" src="static/ueditor/editor_api.js" ></script> <script type="text/javascript" src="static/ueditor/lang/zh-cn/zh-cn.js" ></script> </body> </html>
組件
-
文件目錄
-
核心代碼
src/components/UEditor/index.vue<template> <div class="custom-ueditor-container"> <div :id="id" :style="{ width: width + 'px', height: height + 'px' }" ></div> <multiple-upload class="custom-upload-button" :button-style="buttonStyle" @success="imageSuccess" /> </div> </template> <script> /* eslint-disable eqeqeq */ /* eslint-disable no-undef */ /* eslint-disable no-unused-vars */ /* eslint-disable space-in-parens */ import axios from "axios"; import config from "./config"; // 配置文件見下文 import MultipleUpload from "../MultipleUpload"; // MultipleUpload組件參考 https://blog.csdn.net/qq_39953537/article/details/100039094 import { uploadHtml } from "@/api/upload"; // 接口根據自己後端提供的寫 const UE = window.UE; // 設置 UEDITOR_HOME_URL window.UEDITOR_HOME_URL = "static/ueditor"; export default { components: { MultipleUpload }, props: { width: { type: Number, default: 750 }, height: { type: Number, default: 400 }, html: { type: String, default: "" } }, data() { return { ueditor: null, buttonStyle: { padding: "3px 6px" } }; }, computed: { // 生成唯一id id() { const id = Math.random() .toString(36) .substring(2, 15) + "-ueditor-" + +new Date(); return id; } }, watch: { html(val) { this.loadUrl(val); } }, mounted() { this.init(); }, beforeDestroy() { this.destroyEditor(); }, methods: { // 編輯器初始化 init() { this.ueditor = UE.getEditor(this.id, { ...config }); if (this.html) { this.loadUrl(this.html); } }, // 加載html內容 async loadUrl(url) { try { const { data } = await axios.get(url); this.setContent(data); } catch (error) { this.setContent("服務器數據加載失敗,請重試!"); } }, // 圖片上傳成功添加到編輯器 async imageSuccess(urlList) { try { let imageTemplateList = ""; urlList.forEach(item => { const image = `<img style="max-width:100%;" src="${item}">`; imageTemplateList = imageTemplateList + image; }); this.inserthtml(imageTemplateList, true); this.$message.success("上傳成功!"); } catch (error) { console.log(error); this.$message.error(error); } }, // 編輯器內容上傳到cos,調用返回url async content2Url() { try { if (!this.hasContent()) { throw new Error("未輸入內容"); } const content = this.getContent(); const res = await uploadHtml(content); return res; } catch (error) { throw new Error(error); } }, // 設置編輯器內容 isAppendTo爲true時是追加內容到編輯器,false是覆蓋 setContent(content, isAppendTo) { if (!content) return; this.ueditor.ready(() => { this.ueditor.setContent(content, isAppendTo); }); }, // 在當前光標位置插入html內容 inserthtml(content) { if (!content) return; this.ueditor.execCommand("inserthtml", content); }, // 獲取編輯器內容 getContent() { return this.ueditor.getContent(); }, // 設置編輯器聚焦 setFocus() { this.ueditor.focus(); }, // 判斷編輯器是否有內容 hasContent() { return this.ueditor.hasContents(); }, // 銷燬編輯器 destroyEditor() { this.ueditor.destroy(); } } }; </script> <style lang="scss" scoped> .custom-ueditor-container { position: relative; color: #373737; line-height: 22px; .custom-upload-button { position: absolute; left: 650px; top: 32px; z-index: 99; } } </style> <style> /* 添加135編輯器插件樣式 */ .edui-button.edui-for-135editor .edui-button-wrap .edui-button-body .edui-icon { background-image: url("http://static.135editor.com/img/icons/editor-135-icon.png") !important; background-size: 85%; background-position: center; background-repeat: no-repeat; } </style>
src/components/UEditor/config/index.js
import toolbars from "./toolbars"; const config = { toolbars, zIndex: 99, // 編輯器層級的基數,默認是900 wordCount: false, // 是否開啓字數統計 wordCountMsg: "", // 輸入提示 maximumWords: Number.MAX_VALUE, // 允許的最大字符數 serverUrl: "", // 服務器統一請求接口路徑 enableAutoSave: false, // 不自動保存 enableContextMenu: false, // 禁用右鍵 autoHeightEnabled: false, // 不自動擴展編輯器高度 elementPathEnabled: false // 不顯示html元素路徑 }; export default config;
src/components/UEditor/config/toolbars.js
const toolbars = [ [ // 'fullscreen', // 全屏 // 'source', // 源代碼 // '|', // 'undo', // 'redo', // '|', "bold", "italic", "underline", "fontborder", "strikethrough", "superscript", "subscript", "removeformat", "formatmatch", "autotypeset", "blockquote", "pasteplain", "|", "forecolor", "backcolor", // 'insertorderedlist', // 有序 // 'insertunorderedlist', // 無序 "selectall", "cleardoc", "|", "rowspacingtop", "rowspacingbottom", "lineheight", "|", // 'customstyle', "paragraph", // 'fontfamily', "fontsize", "|", // 'directionalityltr', // 文字方向 // 'directionalityrtl', // 文字方向 "indent", "|", "justifyleft", "justifycenter", "justifyright", "justifyjustify", "|", "touppercase", "tolowercase", // '|', // 'link', // 'unlink', // 'anchor', "|", "imagenone", "imageleft", "imageright", "imagecenter", "|", // 'simpleupload', // 'insertimage', "emotion", // 'scrawl', // 塗鴉 // 'insertvideo', // 'music', // 'attachment', // 附件 // 'map', // 'gmap', // 'insertframe', // 'insertcode', // 'webapp', // 'pagebreak', // 分頁 "template", // 'background', // 編輯器背景 "|", "horizontal", "date", "time", "spechars", // 'snapscreen', // 截圖 // 'wordimage', // '|', // 'inserttable', // 'deletetable', // 'insertparagraphbeforetable', // 'insertrow', // 'deleterow', // 'insertcol', // 'deletecol', // 'mergecells', // 'mergeright', // 'mergedown', // 'splittocells', // 'splittorows', // 'splittocols', // 'charts', "|", // 'print', // 'preview', "searchreplace" // 'help', // 'drafts' ] ]; export default toolbars;
-
使用
<template> <div class="demo"> <u-editor ref="editor" :height="500" :html="html" @input="getContent" /> <div class="get-url-btn-warpper"> <el-button type="primary" size="small" @click="getContentUrl"> 獲取上傳後的鏈接 </el-button> </div> </div> </template> <script> import UEditor from '@/components/UEditor' export default { name: 'UEditorDemo', components: { UEditor }, data() { return { html: '', content: '' } }, methods: { // 獲取商品詳情編輯器內容 getContent(content) { this.content = content }, // 獲取上傳後的鏈接 async getContentUrl() { try { const url = await this.$refs.editor.content2Url() console.log(url) } catch (error) { this.$message.warning(error.message) } } } } </script> <style lang="scss"> .demo { margin: 50px; } .get-url-btn-warpper { margin-top: 10px; } </style>
-
使用效果
參考鏈接