79 lines
1.8 KiB
Vue
79 lines
1.8 KiB
Vue
<template>
|
|
<div class="rich-editor-wrap">
|
|
<Toolbar
|
|
:editor="editorRef"
|
|
:default-config="toolbarConfig"
|
|
:mode="mode"
|
|
class="rich-editor-toolbar"
|
|
/>
|
|
<Editor
|
|
v-model="editorValue"
|
|
:default-config="editorConfig"
|
|
:mode="mode"
|
|
style="height: 400px; overflow-y: hidden;"
|
|
@on-created="onCreated"
|
|
@on-change="handleChange"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, shallowRef, computed, onBeforeUnmount } from 'vue'
|
|
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
|
import '@wangeditor/editor/dist/css/style.css'
|
|
|
|
const props = defineProps({
|
|
modelValue: { type: String, default: '' },
|
|
placeholder: { type: String, default: '请输入内容...' },
|
|
mode: { type: String, default: 'default' } // 'default' | 'simple'
|
|
})
|
|
const emit = defineEmits(['update:modelValue', 'change'])
|
|
|
|
// prop 是只读的, 用 computed 中转
|
|
const editorValue = computed({
|
|
get: () => props.modelValue,
|
|
set: (val) => emit('update:modelValue', val)
|
|
})
|
|
|
|
const editorRef = shallowRef(null)
|
|
|
|
const toolbarConfig = {
|
|
excludeKeys: [
|
|
'group-video', // 视频上传, 避免服务器无视频上传接口
|
|
'insertVideo',
|
|
'uploadVideo'
|
|
]
|
|
}
|
|
const editorConfig = {
|
|
placeholder: props.placeholder,
|
|
MENU_CONF: {
|
|
uploadImage: {
|
|
// 简化: 不接图片上传接口, 用户直接粘贴/拖拽本地图片由浏览器转 base64
|
|
customUpload: () => {}
|
|
}
|
|
}
|
|
}
|
|
|
|
function onCreated(editor) {
|
|
editorRef.value = editor
|
|
}
|
|
function handleChange(editor) {
|
|
emit('change', editor.getHtml())
|
|
}
|
|
|
|
onBeforeUnmount(() => {
|
|
const editor = editorRef.value
|
|
if (editor) editor.destroy()
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.rich-editor-wrap {
|
|
border: 1px solid #dcdfe6;
|
|
border-radius: 4px;
|
|
background: #fff;
|
|
}
|
|
.rich-editor-toolbar {
|
|
border-bottom: 1px solid #dcdfe6;
|
|
}
|
|
</style> |