Article directory
- 1. ueditor (Baidu Rich Text Editor)
-
- Install
- Use and re-package components
- 2. KindEditor
-
- download file
- Create new components and use them
1. ueditor (Baidu Rich Text Editor)
Reference ueditor and vue-ueditor-wrap
The encapsulated vue component is used directly herevue-ueditor-wrap
vue3 version
Installation
npm i [email protected] -S or yarn add [email protected]
Use and re-encapsulate components
- main.ts
import VueUeditorWrap from 'vue-ueditor-wrap'; import App from '@/App/index.vue'; const app = createApp(App).use(VueUeditorWrap)
- ueditor/index.vue
<template> <vue-ueditor-wrap v-model="content" :config="VueUeditorWrapConfig" :editor-id="editorId" ></vue-ueditor-wrap> </template> <script> import {<!-- --> default as VueUeditorWrapConfig } from "./ueditor.js"; import {<!-- --> RandomNumber } from '@/utils' export default {<!-- --> props: {<!-- --> value: [String], property: {<!-- --> type: Object, default() {<!-- --> return {<!-- -->}; }, }, }, model: {<!-- --> prop: "value", // Specify the name of the parameter to be bound by v-model, which comes from the parameters defined in props event: "change", // Specify the event name to be triggered, which will be used for $emit }, data() {<!-- --> return {<!-- --> show: false, VueUeditorWrapConfig, isPosting: false, edit_show: true, index: 0, editorId: 'editor' + RandomNumber() }; }, computed: {<!-- --> content: {<!-- --> get() {<!-- --> return this.value; }, set(val) {<!-- --> this.$emit("change", val); }, }, }, }; </script> <style lang="less" scoped> /* Pop-up input box length */ .lengthWidth {<!-- --> width: 80%; } .editor_if {<!-- --> width: 100%; height: 400px; } .edui1 {<!-- --> z-index: 90 !important; } </style>
- ueditor/ueditor.js
// let env = process.env.NODE_ENV || '' let ueditorPath = '' // if (env === 'development') {<!-- --> // ueditorPath = '/static/UEditor/' // } else if (env === 'production') {<!-- --> // ueditorPath = '/static/UEditor/' // } else {<!-- --> // ueditorPath = '/static/UEditor/' // } ueditorPath = '/ueditor/' export default {<!-- --> UEDITOR_HOME_URL: ueditorPath, maximumWords: 1000 * 100, // toolbars: [ //[ // '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', '|', // 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|', // 'horizontal', 'date', 'time', // 'inserttable', 'simpleupload', 'preview', // ] // ], toolbars: [ [ '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', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|', 'horizontal' ] ], enableAutoSave: false, elementPathEnabled: false, disabledTableInTable: false, serverUrl: '' // No interface yet APP_CONFIG.baseURL + '/file/upload' }
Using the above defined components can display the following effect:
2. KindEditor
Download file
kindeditor
Place in local static directory
New components and usage
Create the following folders and files in the component folder
- kind-editor/index.vue
<template> <div class="kindeditor"> <textarea :id="id" name="content" v-model="state.outContent"></textarea> </div> </template> <script lang="ts"> import {<!-- --> defineComponent, onMounted, reactive, watch } from "vue" import '@public/kind-editor/themes/default/default.css' import '@public/kind-editor/kindeditor-all.js' import '@public/kind-editor/lang/zh-CN.js' import '@public/kind-editor/lang/en.js' export default defineComponent({<!-- --> name: 'kind-editor', props: {<!-- --> modelValue: {<!-- --> type: String, default: '' }, id: {<!-- --> type: String, required: true }, width: {<!-- --> type: String }, height: {<!-- --> type: String }, minWidth: {<!-- --> type: Number, default: 650 }, minHeight: {<!-- --> type: Number, default: 100 }, items: {<!-- --> type: Array, default: function () {<!-- --> return [ 'source', '|', 'undo', 'redo', '|', 'preview', 'print', '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', 'media', 'insertfile', 'table', 'hr', 'pagebreak', 'anchor', 'link', 'unlink', ] } }, noDisableItems: {<!-- --> type: Array, default: function () {<!-- --> return ['source', 'fullscreen'] } }, filterMode: {<!-- --> type: Boolean, default: true }, htmlTags: {<!-- --> type: Object, default: function () {<!-- --> return {<!-- --> 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': [] } } }, wellFormatMode: {<!-- --> type: Boolean, default: true }, resizeType: {<!-- --> type: Number, default: 2 }, themeType: {<!-- --> type: String, default: 'default' }, langType: {<!-- --> type: String, default: 'en' }, 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 }, bodyClass: {<!-- --> type: String, default: 'ke-content' }, colorTable: {<!-- --> type: Array }, afterCreate: {<!-- --> type: Function }, afterChange: {<!-- --> type: Function }, afterTab: {<!-- --> type: Function }, afterFocus: {<!-- --> type: Function }, afterBlur: {<!-- --> type: Function }, afterUpload: {<!-- --> type: Function }, uploadJson: {<!-- --> type: String }, fileManagerJson: {<!-- --> type: Function }, 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 }, fontSizeTable: {<!-- --> type: Array, default: function () {<!-- --> return ['9px', '10px', '12px', '14px', '16px', '18px', '24px', '32px'] } }, imageTabIndex: {<!-- --> type: Number, default: 0 }, formatUploadUrl: {<!-- --> type: Boolean, default: true }, fullscreenShortcut: {<!-- --> type: Boolean, default: false }, extraFileUploadParams: {<!-- --> type: Array, 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 } }, setup(props, {<!-- --> emit }) {<!-- --> const state = reactive({<!-- --> editor: {<!-- -->} as any, outContent: props.modelValue }) console.log('state_state', state) watch(() => props.modelValue, (val: any) => {<!-- --> state.editor & amp; & amp; val !== state.outContent & amp; & amp; state.editor.html(val) }) watch(() => state.outContent, (val: any) => {<!-- --> emit('update:modelValue', val) }) onMounted(async() => {<!-- --> state.editor = (window as any).KindEditor.create('#' + props.id, {<!-- --> width: props.width, height: props.height, minWidth: props.minWidth, minHeight: props.minHeight, items: props.items, noDisableItems: props.noDisableItems, filterMode: props.filterMode, htmlTags: props.htmlTags, wellFormatMode: props.wellFormatMode, resizeType: props.resizeType, themeType: props.themeType, langType: props.langType, designMode: props.designMode, fullscreenMode: props.fullscreenMode, basePath: props.basePath, themesPath: props.cssPath, pluginsPath: props.pluginsPath, langPath: props.langPath, minChangeSize: props.minChangeSize, loadStyleMode: props.loadStyleMode, urlType: props.urlType, newlineTag: props.newlineTag, pasteType: props.pasteType, dialogAlignType: props.dialogAlignType, shadowMode: props.shadowMode, zIndex: props.zIndex, useContextmenu: props.useContextmenu, syncType: props.syncType, indentChar: props.indentChar, cssPath: props.cssPath, cssData: props.cssData, bodyClass: props.bodyClass, colorTable: props.colorTable, afterCreate: props.afterCreate, afterChange: function () {<!-- --> props.afterChange state.outContent = this.html() }, afterTab: props.afterTab, afterFocus: props.afterFocus, afterBlur: props.afterBlur, afterUpload: props.afterUpload, uploadJson: props.uploadJson, fileManagerJson: props.fileManagerJson, allowPreviewEmoticons: props.allowPreviewEmoticons, allowImageUpload: props.allowImageUpload, allowFlashUpload: props.allowFlashUpload, allowMediaUpload: props.allowMediaUpload, allowFileUpload: props.allowFileUpload, allowFileManager: props.allowFileManager, fontSizeTable: props.fontSizeTable, imageTabIndex: props.imageTabIndex, formatUploadUrl: props.formatUploadUrl, fullscreenShortcut: props.fullscreenShortcut, extraFileUploadParams: props.extraFileUploadParams, filePostName: props.filePostName, fillDescAfterUploadImage: props.fillDescAfterUploadImage, afterSelectFile: props.afterSelectFile, pagebreakHtml: props.pagebreakHtml, allowImageRemote: props.allowImageRemote, autoHeightMode: props.autoHeightMode, fixToolBar: props.fixToolBar, tabIndex: props.tabIndex }) }) return {<!-- --> state } } }) </script> <style> </style>
- use
<KindEditor id="KindEditor012" />
import KindEditor from '@/component/kind-editor/index.vue' export default defineComponent({<!-- --> components: {<!-- --> KindEditor }, setup() {<!-- --> return {<!-- --> \t\t } }
- Effect