Vue3 中使用富文本编辑器 wangeditor
Vue3中使用富文本编辑器 wangeditor
一、概述
在Vue3项目中使用wangEditor富文本编辑器,提供完整的文本编辑、图片上传、视频上传等功能。wangEditor是一款轻量级、功能丰富的Web富文本编辑器,特别适合Vue3项目集成。
二、实现步骤
2.1 安装依赖
官网地址 wangEditor5官网
yarn add @wangeditor/editor
# 或者 npm install @wangeditor/editor --saveyarn add @wangeditor/editor-for-vue@next
# 或者 npm install @wangeditor/editor-for-vue@next --save
2.2 组件封装
完整组件代码
<script setup lang="ts">import '@wangeditor/editor/dist/css/style.css'import { Editor, InsertFnType, Toolbar } from '@wangeditor/editor-for-vue'import { getEnv, resolveBaseUrl } from '@nofar-core/utils'const emits = defineEmits(['update:modelValue', 'change'])const props = defineProps({modelValue: {type: String,default: ''},contentHeight: {type: String,default: '300px'}})const valueHtml = computed({get() {return props.modelValue},set(value: string) {emits('update:modelValue', value)}})// 编辑器实例,必须用 shallowRefconst editorRef = shallowRef()const mode = ref('default')const toolbarConfig = {excludeKeys: []// 添加字体配置}interface MenuConf {uploadImage?: anyuploadVideo?: any[key: string]: any}const editorConfig = {placeholder: '请输入内容...',MENU_CONF: {} as MenuConf// 添加字体和字号配置}const { accessToken } = useToken()const baseUrl = getEnv('BASE_API') ?? '/api'interface UploadResponse {body: {filePath: string}}// 修改 uploadImage 配置editorConfig.MENU_CONF['uploadImage'] = {// 服务端地址,必填server: `${baseUrl}/AuthorityServer/file/upload`,fieldName: 'file',// 单个文件的最大体积限制,默认为 2MmaxFileSize: 50 * 1024 * 1024, // 50M// 最多可上传几个文件,默认为 100maxNumberOfFiles: 1,// 跨域是否传递 cookie ,默认为 falsewithCredentials: true,// 自定义增加 http headerheaders: {Authorization: accessToken,From: 'web'},// 超时时间,默认为 10 秒timeout: 15 * 1000, // 15s// 自定义插入图片customInsert(res: UploadResponse, insertFn: InsertFnType) {const url = resolveBaseUrl(res.body.filePath);(insertFn as (url: string, alt: string) => void)(url, '')}}// 修改 uploadVideo 配置editorConfig.MENU_CONF['uploadVideo'] = {server: `${baseUrl}/AuthorityServer/file/upload`,fieldName: 'file',maxFileSize: 50 * 1024 * 1024,maxNumberOfFiles: 1,withCredentials: true,headers: {Authorization: accessToken,From: 'web'},timeout: 15 * 1000,customInsert(res: UploadResponse, insertFn: InsertFnType) {const url = resolveBaseUrl(res.body.filePath);(insertFn as (url: string, alt: string) => void)(url, '')}}// 组件销毁时,也及时销毁编辑器,重要!onBeforeUnmount(() => {const editor = editorRef.valueif (editor == null) returneditor.destroy()})// 编辑器回调函数const handleCreated = (editor: any) => {editorRef.value = editor // 记录 editor 实例,重要!}function handleChange(editor: { getHtml: () => any }) {emits('change', editor.getHtml())}
</script><template><div class="editor_box z-[1] border-1 border-color-[#ccc]"><Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :default-config="toolbarConfig" :mode="mode" /><Editor v-model="valueHtml" :style="'height:' + contentHeight" :default-config="editorConfig" :mode="mode" @on-change="handleChange" @on-created="handleCreated" /></div>
</template><style lang="scss">.editor_box {border-radius: 8px;h1 {font-size: 2em;font-weight: bold;}h2 {font-size: 1.5em;font-weight: bold;}h3 {font-size: 1.17em;font-weight: bold;}h4 {font-size: 1em;font-weight: bold;}h5 {font-size: 0.83em;font-weight: bold;}}.w-e-toolbar {// background-color: #e4e7ed;border-radius: 8px 8px 0 0;}.w-e-text-container {border-radius: 8px;}.w-e-scroll {border-radius: 8px;}
</style>
模板说明:
- Toolbar:独立的工具栏组件
- Editor:编辑器主题组件
- 采用上下布局:工具栏 + 编辑区域
参数说明:
- modelValue:实现v-model双向绑定的值
- contentHeight:编辑器高度,默认为300px
- update:modelValue:v-model更新事件
- change:内容变化回调事件
关键技术:
- computed + get/set:用于创建支持 v-model 的可复用表单组件(它让组件可以像原生表单元素一样使用 v-model,提高了组件的复用性和易用性。)
- shallowRef:浅层响应式引用,适合编辑器实例
- mode:支持’default’和’simple’两种模式
2.3 在父组件中使用
<script setup lang="ts">import Editor from '@/components/Editor/index.vue'const form = reactive<Partial<AlertProcess>>({remark: '',name: ''})const handleSubmit = () => {console.log('提交数据:', form)// 提交逻辑...}
</script><template><el-dialog draggable><el-form ref="formRef" :model="form" label-width="auto" :rules="rules"><el-form-item label="广告名称" prop="name"><el-input v-model="form.name" resize="none"></el-input></el-form-item><el-form-item label="备注" prop="remark"><Editor v-model="form.remark" /></el-form-item></el-form><template #footer><el-button @click="handleClose">取消 </el-button><el-button type="primary" @click="handleSubmit"> 确定</el-button></template></el-dialog>
</template>
2.4 实现效果
编辑器
