wangeditor官网
- vue3中使用下载依赖
yarn add @wangeditor/editor
yarn add @wangeditor/editor-for-vue@next
- 组件封装
<template>
<div style="border: 1px solid #ccc">
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
<Editor style="height: 380px; overflow-y: hidden" v-model="currentText" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" />
</div>
</template>
<script setup>
import { onBeforeUnmount, watch, defineProps, shallowRef, reactive, defineEmits, toRefs } from 'vue';
import '@wangeditor/editor/dist/css/style.css';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { toolbarKeys } from './toolbar';
import Cookies from 'js-cookie';
import { ElMessage } from 'element-plus';
const emits = defineEmits(['update:modelValue']);
const state = reactive({
mode: 'default',
currentText: '',
});
const { mode, currentText } = toRefs(state);
const props = defineProps({
valueHtml: String,
isDisable: {
type: Boolean,
default: () => false,
},
});
const editorRef = shallowRef();
const toolbarConfig = {
toolbarKeys,
};
const editorConfig = {
placeholder: '请输入内容...',
readOnly: props.isDisable,
MENU_CONF: {
uploadImage: {
server: import.meta.env.VITE_API_URL + 'notice/upload',
fieldName: 'file',
headers: {
Authorization: `Bearer ${Cookies.get('token')}` || '',
},
maxFileSize: 10 * 1024 * 1024,
maxNumberOfFiles: 10,
base64LimitSize: 10 * 1024,
timeout: 5 * 1000,
onBeforeUpload(file) {
return file;
},
onError(file, err) {
const temp = 'Error: bg_img.svg exceeds maximum allowed size of 10 MB';
const msg = err == temp ? '超出上限10M!' : msg;
ElMessage({
showClose: true,
message: msg,
type: 'warning',
});
return false;
},
},
},
};
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
const handleCreated = (editor) => {
editorRef.value = editor;
};
watch(
() => props.valueHtml,
(val) => {
currentText.value = val;
},
{
immediate: true,
}
);
watch(
() => currentText.value,
(val) => {
emits('update:modelValue', val);
}
);
</script>
<style>
.w-e-text-placeholder {
top: 10px;
}
</style>
export const toolbarKeys = [
'headerSelect',
'blockquote',
'bold',
'underline',
'italic',
{
key: 'group-more-style',
title: '更多',
iconSvg:
'<svg viewBox="0 0 1024 1024"><path d="M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path></svg>',
menuKeys: ['through', 'code', 'sup', 'sub', 'clearStyle'],
},
'color',
'bgColor',
'fontSize',
'fontFamily',
'lineHeight',
'bulletedList',
'numberedList',
'todo',
{
key: 'group-justify',
title: '对齐',
iconSvg:
'<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>',
menuKeys: ['justifyLeft', 'justifyRight', 'justifyCenter'],
},
{
key: 'group-indent',
title: '缩进',
iconSvg:
'<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z"></path></svg>',
menuKeys: ['indent', 'delIndent'],
},
'emotion',
'insertLink',
{
key: 'group-image',
title: '图片',
iconSvg:
'<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>',
menuKeys: ['uploadImage','insertImage'],
},
'insertTable',
'codeBlock',
'divider',
'undo',
'redo',
];
- 组件中使用
import Editor from '@/components/editor/index.vue';
<Editor :valueHtml="state.formData.content" v-model="state.formData.content" />