当前位置: 首页 > news >正文

wangEditor

快速开始 | wangEditor

很多后台系统(例如文章管理、公告编辑)都需要一个富文本编辑器。wangEditor 是一个轻量、好用的编辑器,非常适合在 Vue 项目里使用。
本文会从 零开始 带你实现一个可复用的 RichEditor.vue,并讲清楚 v-model 的原理

一、安装依赖

在 Vue3 项目里(例如 Vite + Vue3)安装最新的 wangEditor:

# 如果装过旧版本(wangeditor),先卸载
npm uninstall wangeditor# 安装 v5
npm install @wangeditor/editor @wangeditor/editor-for-vue@next

二、封装组件 RichEditor.vue

新建 src/components/RichEditor.vue

<template><div class="editor-wrap"><!-- 工具栏 --><Toolbar :editor="editorRef" :mode="mode" class="toolbar" /><!-- 编辑区 --><Editorv-model="valueHtml":defaultConfig="editorConfig":mode="mode"@onCreated="handleCreated"class="editor"/></div>
</template><script setup>
import { ref, shallowRef, watch, onBeforeUnmount } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import '@wangeditor/editor/dist/css/style.css'// 父组件通过 v-model 传进来的值
const props = defineProps({modelValue: { type: String, default: '' },mode: { type: String, default: 'default' }
})
const emit = defineEmits(['update:modelValue', 'change'])const editorRef = shallowRef(null)         // 编辑器实例
const valueHtml = ref(props.modelValue)    // 编辑器内容
const editorConfig = { placeholder: '请输入内容...' }function handleCreated(editor) {editorRef.value = editor
}// 内容变化时,通知父组件
watch(valueHtml, (val) => {emit('update:modelValue', val)  // 支持 v-modelemit('change', val)             // 自定义事件(可选)
})// 父组件传入的值变化时,同步到编辑器
watch(() => props.modelValue, (val) => {if (val !== valueHtml.value) valueHtml.value = val
})onBeforeUnmount(() => {const editor = editorRef.valueif (editor) editor.destroy()
})
</script><style>
.editor-wrap { border: 1px solid #ddd; border-radius: 6px; }
.toolbar { border-bottom: 1px solid #eee; }
.editor { min-height: 300px; padding: 10px; }
</style>

三、在 App.vue 中测试使用

<template><div id="app" style="padding:24px"><h2>wangEditor 测试</h2><!-- 通过 v-model 绑定内容 --><RichEditor v-model="content" @change="onChange" /><div style="margin-top:16px;"><h3>当前内容(HTML 打印)</h3><pre>{{ content }}</pre><h3>当前内容(预览效果)</h3><div v-html="content" style="border:1px dashed #ccc;padding:10px;"></div></div></div>
</template><script setup>
import { ref } from 'vue'
import RichEditor from './components/RichEditor.vue'const content = ref('<p>hello wangEditor</p>')// 监听 change 事件
function onChange(val) {console.log('内容变化:', val)
}
</script>

四、关键点解析

v-model 的原理

当你写:

<RichEditor v-model="content" />

Vue 会自动转换成:

<RichEditor :modelValue="content" @update:modelValue="val => content = val" />

也就是说:

  • :modelValue="content" 👉 父组件把值传给子组件

  • @update:modelValue="..." 👉 子组件内容变了,通知父组件更新

所以子组件必须写:

defineProps({ modelValue: String })
defineEmits(['update:modelValue'])

Vue2 的 v-model

在 Vue2 里,v-model 默认约定:

  • 绑定的 prop 名value

  • 触发的 事件名input

比如父组件:

<MyInput v-model="msg" />

会被编译成:

<MyInput :value="msg" @input="msg = $event" />

所以,子组件必须写:

props: {value: String
},
methods: {update(val) {this.$emit('input', val)   // 触发 input 事件,父组件才能更新}
}

总结

  • Vue2:v-model = :value + @input

  • Vue3:v-model = :modelValue + @update:modelValue

为什么还要 emit('change', val)?

update:modelValue 是专门给 v-model 用的。
change 是我们自定义的事件。父组件可以用:

<RichEditor v-model="content" @change="onChange" />

这样可以在内容变化时做额外的处理(比如实时保存草稿)。


如何修改菜单配置(上传图片,视频)

菜单配置 | wangEditor

  • 上传图片editorConfig.MENU_CONF.uploadImage 菜单配置 | 上传图片-wangEditor

  • 上传视频editorConfig.MENU_CONF.uploadVideo 菜单配置 |上传视频- wangEditor

默认配置
如果你啥也不配,编辑器的“上传图片/视频”按钮是不能用的,因为它没有上传地址。

如何改配置
你在创建编辑器时传入 editorConfig,里面写上 MENU_CONF,就能修改默认菜单的行为。

Vue3 (setup) 示例:

const editorConfig = {MENU_CONF: {uploadImage: {server: '/api/upload/image',fieldName: 'file',maxFileSize: 2 * 1024 * 1024, // 2M},uploadVideo: {server: '/api/upload/video',fieldName: 'file',maxFileSize: 50 * 1024 * 1024, // 50M}}
}

返回格式

  • 官方推荐后端返回:

    { "errno": 0, "data": { "url": "http://xxx/yyy.png" } }
    

如果后端返回格式不一样,就用 customInsert 自己解析,并把 url 插入到编辑器里。

示例配置(结合若依)

const editorConfig = {MENU_CONF: {uploadImage: {server: '/api/common/upload',   // RuoYi 通用上传接口fieldName: 'file',headers: { Authorization: 'Bearer ' + localStorage.getItem('token') },customInsert(res, insertFn) {// RuoYi 返回格式 { code:200, url:"/profile/upload/xxx.png" }if (res.code === 200 && res.url) {insertFn(res.url)   // 插入图片,可以实现回显}}}}
}
  • reswangEditor 自动传入的后端返回结果

  • insertFnwangEditor 内置的插入函数

  • 你只需要写逻辑,从 res 里取出正确的 URL,再 insertFn(url)

总结上传图片和上传视频的配置示例

const editorConfig = {MENU_CONF: {// 图片上传uploadImage: {server: '/api/upload/image',fieldName: 'file',allowedFileTypes: ['image/*'], // 只允许图片maxFileSize: 5 * 1024 * 1024, // 5McustomInsert(res, insertFn) {if (res.code === 200 && res.url) {insertFn(res.url) // 插入 <img src="...">}}},// 视频上传uploadVideo: {server: '/api/upload/video',fieldName: 'file',allowedFileTypes: ['video/*'], // 只允许视频maxFileSize: 50 * 1024 * 1024, // 50McustomInsert(res, insertFn) {if (res.code === 200 && res.url) {insertFn(res.url) // 插入 <video src="..." controls>}}}}
}

http://www.dtcms.com/a/465348.html

相关文章:

  • Unity网络开发--超文本传输协议Http(1)
  • 从“用框架”到“控系统”——数据流、事件流、接口边界是如何形成的;
  • 有没有什么网站做泰国的东西做网站排名软件
  • 达梦数据库逻辑备份与还原
  • 如何解决Redis和数据库的一致性问题?
  • 新版saas餐饮外卖小程序源码/微信/支付宝/抖音/扫码点餐/DIY装修/美团代付/全开源
  • react 修复403页面无法在首页跳转问题
  • 学子网站建设郑州门户网站建设哪家好
  • 新乡网站优化公司看市场行情用什么软件
  • SQL注入原理与方法
  • 如何将Vue 项目转换为 Android App(使用Capacitor)
  • 输出端口原理图分析
  • 响应式网站建设有利于seo常熟做网站公司
  • php购物网站开发设计免费网站软件app
  • CTF攻防世界WEB精选基础入门:disabled_button
  • 昂瑞微:引领射频前端国产化浪潮,铸就5G时代核心竞争力
  • 基于SpringBoot的高校教师科研项目信息管理系统
  • 富文本返回的Html数据格式化
  • 昂瑞微冲刺科创板:创新驱动,引领射频芯片国产化新征程
  • 基于Java(Spring Boot)+MySQL实现电商网站
  • 记录一次生产环境数据库死锁的处理过程
  • 首先确定网站建设的功能定位seo推广工具
  • Nestjs框架: Pino 与 Pino-Elasticsearch 组合实现高性能日志写入与检索的完整方案
  • 走近实验技术中的“四大发明”之Southern blot、Northern blot和Western blot
  • 网站建设需求文档模板下载想做电商从哪里入手
  • ai做网站建站做得好的公司
  • 网络层--数据链路层
  • 网站设计应该遵循哪些原则手机网站打开手机app
  • 【AI安全】Qwen3Guard: 实时流式检测实现AI模型安全防护新标杆
  • 网络攻防技术:网络安全攻击概述