vue後臺管理系統富文本組件(二)kindeditor
簡介
富文本組件作爲後臺管理系統的最重要的基礎組件之一,好多公司還是習慣使用kindeditor。雖然他的界面比較老,但是相當穩定bug少。
主要依賴說明 (先安裝,步驟略)
{
"axios": "^0.18.0",
"element-ui": "2.11.1",
"vue": "^2.6.10",
"kindeditor": "^4.1.10",
}
正文
1.組件
文件目錄
src/components/Kindeditor/index.vue
<template>
<div class="margin-top-20">
<textarea :id="id" name="content" v-model="outContent"></textarea>
<input
@change="selectedFile"
style="visibility: hidden;height:0;"
type="file"
name
id="inputFile"
/>
</div>
</template>
<script>
import "kindeditor/themes/default/default.css";
import "kindeditor/kindeditor-all-min.js";
import "kindeditor/lang/zh-CN.js";
// 以下四個配置文件見下文
import items from "./config/items";
import htmlTags from "./config/htmlTags";
import fontSizeTable from "./config/fontSizeTable";
import otherConfig from "./config/otherConfig";
export default {
name: "kindeditor-component",
props: {
// 編輯器內容 url
html: {
type: String,
default: ""
},
// 編輯器內容
content: {
type: String,
default: ""
},
// 編輯器id
id: {
type: String,
// required: true,
default: "kindeditor-id"
},
// 寬
width: {
type: String,
default: `100%`
},
// 高
height: {
type: String,
default: "400"
},
// 最小寬
minWidth: {
type: Number,
default: 650
},
// 最小高
minHeight: {
type: Number,
default: 400
},
// toolbar 工具欄配置
items: {
type: Array,
default: function() {
return [...items];
}
},
// 標籤配置
htmlTags: {
type: Object,
default: function() {
return { ...htmlTags };
}
},
//字號配置
fontSizeTable: {
type: Array,
default: function() {
return [...fontSizeTable];
}
},
// 語言配置
langType: {
type: String,
default: "zh-CN"
},
// 主題配置
themeType: {
type: String,
default: "default"
},
// body 的樣式
bodyClass: {
type: String,
default: "ke-content"
},
// 其他配置項
...otherConfig
},
data() {
return {
editor: null,
outContent: this.content
};
},
watch: {
content(val) {
this.editor && val !== this.outContent && this.editor.html(val);
},
// 分發編輯器內容改變事件
outContent(val) {
this.$emit("update:content", val);
this.$emit("on-content-change", val);
this.$emit("input", val);
},
// 初始化編輯器內容
html(val) {
if (
this.html &&
(this.html.startsWith("https://") || this.html.startsWith("http://"))
) {
this.loadUrl(val);
} else {
this.outContent = "";
this.outContent ? this.editor.appendHtml(this.outContent) : "";
}
}
},
created() {
if (
this.html &&
(this.html.startsWith("https://") || this.html.startsWith("http://"))
) {
this.loadUrl(this.html);
} else {
this.outContent = "";
setTimeout(() => {
this.outContent ? this.editor.appendHtml(this.outContent) : "";
}, 1000);
}
},
mounted() {
// 初始訪問時創建
this.initEditor();
// 添加焦點
// this.editor.focus();
// 添加點擊圖片回調函數
this.editor.clickToolbar("image", () => {
// 禁用自帶的圖片彈窗
this.editor.hideDialog();
// 打開文件
this.handleOpenFile();
});
},
activated() {
// keep-alive 進入時創建
this.initEditor();
},
deactivated() {
// keep-alive 離開時移除
this.removeEditor();
},
beforeDestroy() {
// 實例銷燬之前移除
this.removeEditor();
},
methods: {
// 打開文件
handleOpenFile() {
let input = document.getElementById("inputFile");
// 解決同一個文件不能監聽的問題
input.addEventListener(
"click",
function() {
this.value = "";
},
false
);
// 點擊input
input.click();
},
// 選擇好文件
async selectedFile($event) {
const file = $event.target.files[0];
// 把圖片上傳到後端服務器 拿到url uploadImage 是自己後端上傳圖片的接口
// 調用appendHtml方法把圖片追加到富文本
// const url= await uploadImage (file)
// this.editor.appendHtml(
// `<img style="max-width:100%;" src="https://${data.Location}">`
// );
},
// 編輯器內容上傳到cos,調用返回url
async content2Url() {
// 把html片段上傳到後端服務器 拿到url uploadHtml 是自己後端上傳的接口
// try {
// const res = await uploadHtml(this.outContent)
// return res
// } catch (error) {
// this.$message({
// message: error.data.message,
// type: 'error'
// })
// }
}
// 加載html填充編輯器內容
loadUrl(url) {
if (url && url.length > 0) {
axios.get(url)
.then(response => {
// 處理HTML顯示
this.outContent = response.data;
this.editor.appendHtml(this.outContent);
this.$emit("subLoadUrlToHtml", response.data);
})
.catch(() => {
this.outContent = "服務器數據加載失敗,請重試!";
this.editor.appendHtml(this.outContent);
});
}
},
// 移除編輯器實例
removeEditor() {
window.KindEditor.remove(`#${this.id}`);
},
// 初始化編輯器
initEditor() {
this.removeEditor();
this.editor = window.KindEditor.create("#" + this.id, {
width: this.width,
height: this.height,
minWidth: this.minWidth,
minHeight: this.minHeight,
items: this.items,
noDisableItems: this.noDisableItems,
filterMode: this.filterMode,
htmlTags: this.htmlTags,
wellFormatMode: this.wellFormatMode,
resizeType: this.resizeType,
themeType: this.themeType,
langType: this.langType,
designMode: this.designMode,
fullscreenMode: this.fullscreenMode,
basePath: this.basePath,
themesPath: this.themesPath,
pluginsPath: this.pluginsPath,
langPath: this.langPath,
minChangeSize: this.minChangeSize,
loadStyleMode: this.loadStyleMode,
urlType: this.urlType,
newlineTag: this.newlineTag,
pasteType: this.pasteType,
dialogAlignType: this.dialogAlignType,
shadowMode: this.shadowMode,
zIndex: this.zIndex,
useContextmenu: this.useContextmenu,
syncType: this.syncType,
indentChar: this.indentChar,
cssPath: this.cssPath,
cssData: this.cssData,
bodyClass: this.bodyClass,
colorTable: this.colorTable,
afterCreate: this.afterCreate,
// 編輯器內容改變回調
afterChange: () => {
this.editor ? (this.outContent = this.editor.html()) : "";
},
afterTab: this.afterTab,
afterFocus: this.afterFocus,
afterBlur: this.afterBlur,
afterUpload: this.afterUpload,
uploadJson: this.uploadJson,
fileManagerJson: this.fileManagerJson,
allowPreviewEmoticons: this.allowPreviewEmoticons,
allowImageUpload: this.allowImageUpload,
allowFlashUpload: this.allowFlashUpload,
allowMediaUpload: this.allowMediaUpload,
allowFileUpload: this.allowFileUpload,
allowFileManager: this.allowFileManager,
fontSizeTable: this.fontSizeTable,
imageTabIndex: this.imageTabIndex,
formatUploadUrl: this.formatUploadUrl,
fullscreenShortcut: this.fullscreenShortcut,
extraFileUploadParams: this.extraFileUploadParams,
filePostName: this.filePostName,
fillDescAfterUploadImage: this.fillDescAfterUploadImage,
afterSelectFile: this.afterSelectFile,
pagebreakHtml: this.pagebreakHtml,
allowImageRemote: this.allowImageRemote,
autoHeightMode: this.autoHeightMode,
fixToolBar: this.fixToolBar,
tabIndex: this.tabIndex
});
}
}
};
</script>
<style>
</style>
src/components/Kindeditor/config/items.js
// toolbar配置
const items = [
// "source",
// "|",
"undo",
"redo",
"|",
"preview",
// "print",
// "template",
// "code",
"cut",
"copy",
"paste",
"plainpaste",
"wordpaste",
"|",
"justifyleft",
"justifycenter",
"justifyright",
"justifyfull",
"insertorderedlist",
"insertunorderedlist",
"indent",
"outdent",
"subscript",
"superscript",
"clearhtml",
"quickformat",
// "selectall",
"|",
"fullscreen",
"/",
"formatblock",
// "fontname",
"fontsize",
"|",
"forecolor",
"hilitecolor",
"bold",
"italic",
"underline",
"strikethrough",
"lineheight",
"removeformat",
"|",
"image",
// "multiimage",
// "flash",
// "media",
// "insertfile",
// "table",
"hr",
// "emoticons",
// "baidumap",
"pagebreak",
"anchor",
"link",
"unlink",
"|",
"about"
];
export default items;
src/components/Kindeditor/config/htmlTags.js
const htmlTags = {
font: ["color", "size", "face", ".background-color"],
span: ["style"],
div: ["class", "align", "style"],
table: [
"class",
"border",
"cellspacing",
"cellpadding",
"width",
"height",
"align",
"style"
],
"td,th": [
"class",
"align",
"valign",
"width",
"height",
"colspan",
"rowspan",
"bgcolor",
"style"
],
a: ["class", "href", "target", "name", "style"],
embed: [
"src",
"width",
"height",
"type",
"loop",
"autostart",
"quality",
"style",
"align",
"allowscriptaccess",
"/"
],
img: [
"src",
"width",
"height",
"border",
"alt",
"title",
"align",
"style",
"/"
],
hr: ["class", "/"],
br: ["/"],
"p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6": ["align", "style"],
"tbody,tr,strong,b,sub,sup,em,i,u,strike": []
};
export default htmlTags;
src/components/Kindeditor/config/fontSizeTable.js
// 字體配置
const fontSizeTable = [
"9px",
"10px",
"12px",
"14px",
"16px",
"18px",
"24px",
"32px"
];
export default fontSizeTable;
src/components/Kindeditor/config/otherConfig.js
// 其他非主要配置項
const otherConfig = {
noDisableItems: {
type: Array,
default: function() {
return ["source", "fullscreen"];
}
},
filterMode: {
type: Boolean,
default: true
},
wellFormatMode: {
type: Boolean,
default: true
},
resizeType: {
type: Number,
default: 2
},
designMode: {
type: Boolean,
default: true
},
fullscreenMode: {
type: Boolean,
default: false
},
basePath: {
type: String
},
themesPath: {
type: String
},
pluginsPath: {
type: String,
default: ""
},
langPath: {
type: String
},
minChangeSize: {
type: Number,
default: 5
},
loadStyleMode: {
type: Boolean,
default: true
},
urlType: {
type: String,
default: ""
},
newlineTag: {
type: String,
default: "p"
},
pasteType: {
type: Number,
default: 2
},
dialogAlignType: {
type: String,
default: "page"
},
shadowMode: {
type: Boolean,
default: true
},
zIndex: {
type: Number,
default: 811213
},
useContextmenu: {
type: Boolean,
default: true
},
syncType: {
type: String,
default: "form"
},
indentChar: {
type: String,
default: "\t"
},
cssPath: {
type: [String, Array]
},
cssData: {
type: String
},
colorTable: {
type: Array
},
afterCreate: {
type: Function
},
afterTab: {
type: Function
},
afterFocus: {
type: Function
},
afterBlur: {
type: Function
},
afterUpload: {
type: Function
},
uploadJson: {
type: String
},
fileManagerJson: {
type: String
},
allowPreviewEmoticons: {
type: Boolean,
default: true
},
allowImageUpload: {
type: Boolean,
default: true
},
allowFlashUpload: {
type: Boolean,
default: true
},
allowMediaUpload: {
type: Boolean,
default: true
},
allowFileUpload: {
type: Boolean,
default: true
},
allowFileManager: {
type: Boolean,
default: false
},
imageTabIndex: {
type: Number,
default: 0
},
formatUploadUrl: {
type: Boolean,
default: true
},
fullscreenShortcut: {
type: Boolean,
default: false
},
extraFileUploadParams: {
type: Object,
default: function() {
return {};
}
},
filePostName: {
type: String,
default: "imgFile"
},
fillDescAfterUploadImage: {
type: Boolean,
default: false
},
afterSelectFile: {
type: Function
},
pagebreakHtml: {
type: String,
default: '<hr style="page-break-after: always;" class="ke-pagebreak" />'
},
allowImageRemote: {
type: Boolean,
default: true
},
autoHeightMode: {
type: Boolean,
default: false
},
fixToolBar: {
type: Boolean,
default: false
},
tabIndex: {
type: Number
}
};
export default otherConfig;
2.使用
<template>
<div>
<Kind-editor ref="kindeditor" :html="html" @input="getContent"></Kind-editor>
</div>
</template>
<script>
import KindEditor from "@/components/Kindeditor";
export default {
name: 'GoodsForm',
components: {
KindEditor
},
data() {
return {
html: 'https://ebusiness-1255313385.cosbj.myqcloud.com/image/20190823/center2019082304054532.html',
content:''
}
},
methods: {
// 獲取編輯器內容
getContent(content) {
this.content = content
},
// 編輯器內容轉換成在線url
async getcontent2Url() {
try {
const htmlUrl = await this.$refs.kindeditor.content2Url()
return htmlUrl
} catch (error) {
console.log(error)
}
}
}
}
</script>
3.使用效果