jodit编辑器在vue2中的使用
1.版本
"jodit": "^3.24.4",
"vue": "^2.6.14"
2.安装
npm i jodit@3.24.4
3.基本配置
详细请看代码,本文已经完成了最基本的配置,包括语言选择,自定义tabbar,自定义组件等,详细配置请查看官网(https://xdsoft.net/jodit/docs/modules/config.html)
自定义图标库以及颜色选择: IconRoom.vue
<template>
<div>
<el-popover
placement="bottom"
width="420"
trigger="click"
v-model="visible">
<div class="iconroom-content">
<el-tabs class="iconroom-tabs" tab-position="left">
<el-tab-pane
class="iconroom-tabs-tab"
label="icon1"
v-for="e in 100"
:key="e">
<ul>
<li
class="icon-item"
:class="{ active: icon === i }"
v-for="i in 100"
:key="i"
@click="icon = i">
<i class="el-icon-edit" />
<span class="text" title="编辑箭头啊这是">编辑箭头啊这是</span>
</li>
</ul>
</el-tab-pane>
</el-tabs>
<div class="color-select">
<span
class="color-item"
:class="{ active: color === item }"
v-for="(item, i) in iconColor"
:key="i"
:style="{ background: item }"
@click="color = item"></span>
<el-button size="small" @click="cancelClick">取消</el-button>
<el-button size="small" type="primary" @click="confirmClick"
>导入</el-button
>
</div>
</div>
</el-popover>
</div>
</template>
<script>
export default {
name: 'IconRoom',
props: {
value: {
type: Boolean,
default: false,
},
},
computed: {
visible: {
get() {
return this.value
},
set(value) {
this.$emit('update:value', value)
},
},
},
data() {
return {
iconColor: ['#333333', '#9e9e9e', '#ededed', '#50b4ff', '#ff0000'],
icon: '', // 激活的图标
color: '', // 激活的颜色
}
},
methods: {
cancelClick() {
this.icon = ''
this.color = ''
this.$emit('update:value', false)
},
confirmClick() {
const icon = {
icon: this.icon,
color: this.color,
}
this.$emit('select-icon', icon)
},
},
}
</script>
<style lang="scss" scoped>
.icon-item {
width: 50px;
height: 50px;
margin: 5px;
padding: 5px;
border: 1px solid #eee;
font-size: 12px;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
cursor: pointer;
.text {
width: 50px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
&:hover {
border: 1px solid orange;
}
&.active {
border: 1px solid orange;
}
}
.iconroom-tabs {
height: 400px;
.iconroom-tabs-tab {
overflow: hidden;
ul {
margin: 0;
padding: 0;
height: 400px;
list-style: none;
display: flex;
flex-wrap: wrap;
overflow: hidden;
overflow-y: auto;
}
}
}
.color-select {
border-top: 2px solid #50b4ff;
height: 50px;
margin: 10px;
display: flex;
align-items: center;
justify-content: space-around;
.color-item {
display: inline-block;
width: 35px;
height: 35px;
margin: 5px;
cursor: pointer;
&:hover {
border: 1px solid orange;
}
&.active {
border: 1px solid orange;
}
}
}
</style>
效果图如下所示:
封装的编辑器组件,包括基本配置等自定义标题,tabbar: Editor.vue
<template>
<div class="editor-content">
<IconRoom
:value.sync="iconVisible"
class="icon-room"
@select-icon="selectIcon" />
<textarea id="textarea"> </textarea>
<el-dialog
title="提示"
ref="dialog"
:visible="vivible"
@close="handleClose">
<el-input v-model="text" />
<template slot="footer">
<el-button type="primary" @click="handleClick">提交</el-button>
</template>
</el-dialog>
</div>
</template>
<script>
import 'jodit/build/jodit.min.css'
import { Jodit } from 'jodit'
import IconRoom from './IconRoom.vue'
export default {
name: 'JoditEditor',
props: {
value: { type: String, default: '' },
customConfig: { type: Object, default: () => ({}) },
},
components: { IconRoom },
data() {
return {
editor: null,
vivible: false,
iconVisible: false,
pencil: null,
text: '',
config: {
placeholder: '请输入内容',
readonly: false, // 只读
language: 'zh_cn', // 配置语言
width: '750px', // 设置宽度
height: '100%', // 设置高度
allowResizeX: false, // 是否允许水平提哦啊正大小
allowResizeY: false, // 是否允许垂直调整大小
toolbarButtonSize: 'middle', // 设置按钮大小
theme: 'default', // 主题
statusbar: false, // 是否显示底部状态栏
askBeforePasteFromWprd: false, // 复制粘贴不弹窗提示
askBeforePasteHTML: false,
editHTMLDocumentMode: false,
showBrowerColorPicker: false,
textIcons: false,
iframe: false,
saveSelectionOnBlur: false,
image: {
useImageEditor: true,
},
filebrowser: {
ajax: {
url: '/api',
// method: 'post'
},
fileRemove: {
url: '/api',
method: 'POST',
},
},
uploader: {
insertImageAsBase64URI: true, // 图片上传
// TODO: 修改图片上传接口以及成功和失败的方法
},
// 引入外部CDN
sourceEditorCDNUrlsJS: ['/plugins/ace.js'],
beautifyHTMLCDNUrlsJS: [
'/plugins/beautify.min.js',
'/plugins/beautify-html.min.js',
],
// editorCssClass: false,
triggerChangeEvent: true,
direction: '',
i18n: {
zh_cn: {
top: '上',
right: '右',
bottom: '下',
left: '左',
Title: '标题',
Link: '链接',
'Line height': '行高',
Alternative: '描述',
'Alternative text': '描述',
'Lower Alpha': '小写英文字母',
'Lower Greek': '小写希腊字母',
'Lower Roman': '小写罗马数字',
'Upper Alpha': '大写英文字母',
'Upper Roman': '大写罗马数字',
},
},
// tabIndex: -1,
toolbar: true,
useSplitMode: false,
enter: 'p', // div p
// enterBlock: 'p',
colors: {
list: ['#333333', '#9e9e9e', '#ededed', '#50b4ff'],
},
colorPickerDefaultTab: 'color',
showBrowserColorPicker: false,
imageDefaultWidth: 300,
extraButtons: [
'undo',
'redo',
'copyformat',
'title',
'font',
'fontsize',
'bold',
'underline',
'italic',
'ul',
'ol',
'brush',
'table',
'align',
'pencil',
'image',
],
buttonsMD: [],
buttonsSM: [],
buttonsXS: [],
buttons: [],
},
defaultConfig: {
controls: {
pencil: {
exec: editor => {
this.iconVisible = !this.iconVisible
editor.s.save()
},
},
image: {
icon: 'image',
list: {
uploader: '插入本地图片',
brower: '插入素材库图片',
},
exec: (editor, _, { control }) => {
let key = control.args && control.args[0]
if (key === 'uploader') {
const uploader = new Jodit.modules.Uploader(
editor,
editor.o.uploader
)
uploader.bind(document.getElementById('imageInput'))
} else if (key === 'brower') {
this.vivible = true
editor.s.save()
}
},
childTemplate: (editor, key, value) => {
let isImage = true
if (key === 'uploader') {
return (
'<div id="imageInput" class="jodit-drag-and-drop__file-box">' +
value +
`<input type="file" accept="${
isImage ? 'image/*' : '*'
}" tabindex="-1" dir="auto" multiple=""/>` +
'</div>'
)
} else {
return (
'<div id="imageInput" class="jodit-drag-and-drop__file-box">' +
value +
'</div>'
)
}
},
},
title: {
list: {
h1: '一级标题',
h2: '二级标题',
h3: '三级标题',
},
childTemplate: (editor, key, value) => {
return `<${key} style="margin: 0;padding: 0" class="${key}">${value}</${key}>`
},
exec: (editor, _, { control }) => {
console.log(control)
let value = control.args && control.args[0]
console.log(editor.createInside)
editor.s.applyStyle(undefined, {
// element: value
className: value,
// attributes: value
})
editor.setEditorValue()
return false
},
},
font: {
list: Jodit.atom({
'Thin, sans-serif': 'Thin (35S)',
'UltraLight, sans-serif': 'UltraLight (40S)',
'ExtraLight, sans-serif': 'ExtraLight (45S)',
'Light, sans-serif': 'Light (50S)',
'Book, sans-serif': 'Book (55S)',
'Regular, sans-serif': 'Regular (60S)',
'Medium, sans-serif': 'Medium (65S)',
'DemiBold, sans-serif': 'DemiBold (70S)',
'Bold, sans-serif': 'Bold (75W)',
'Black, sans-serif': 'Black (90W)',
}),
childTemplate: (editor, key, value) => {
return `<span data-style="${key}" style="font-family: ${key}!important">${value}</span>`
},
},
fontsize: {
list: Jodit.atom({
14: '五号',
16: '小四',
19: '四号',
21: '小三',
22: '三号',
24: '小二',
29: '二号',
32: '小一',
35: '一号',
42: '小初',
56: '初号',
// '48': '48'
}),
childTemplate: (editor, key, value) => {
return `${value}`
},
},
},
},
events: {},
}
},
computed: {
editorConfig() {
const config = {
...this.config,
...this.defaultConfig,
...this.customConfig,
}
return config
},
},
watch: {
value(newValue) {
if (this.editor.value !== newValue) this.editor.value = newValue
},
},
mounted() {
this.editor = new Jodit(
document.getElementById('textarea'),
this.editorConfig
)
this.editor.value = this.value
this.editor.events.on('change', newValue => this.$emit('input', newValue))
this.pencil = document.querySelector('.jodit-toolbar-button_pencil')
},
beforeDestroy() {
this.editor.destruct()
},
methods: {
handleClose() {
this.vivible = false
},
handleClick() {
this.editor.s.insertHTML(this.text)
this.vivible = false
},
// 插入图标
selectIcon(data) {
this.editor.s.insertHTML(data)
this.iconVisible = false
},
},
}
</script>
<style lang="scss">
// @import '../../assets/index.css';
.editor-content {
height: 100%;
position: relative;
.icon-room {
position: absolute;
top: 40px;
right: 420px;
}
}
.h1 {
font-size: 56px;
color: #333333;
font-family: 'Regular', sans-serif;
}
.h2 {
font-size: 32px;
color: #333333;
font-family: 'Thin', sans-serif;
}
.h3 {
font-size: 32px;
color: #50b4ff;
font-family: 'Regular', sans-serif;
}
</style>
字体可以根据自己的需求,更换,整体编辑器的效果图如下所示: