引言
在前端开发中,富文本编辑器是一个常见的需求,特别是在需要用户输入大量文本内容的场景中,如博客、内容管理系统等。WangEditor 是一款轻量级、功能丰富的富文本编辑器,本文将详细介绍如何在 Vue 2.7 中使用 WangEditor 5。
安装依赖
首先,我们需要安装 WangEditor 相关的依赖包:
npm install @wangeditor/editor@5.0.1 @wangeditor/editor-for-vue@1.0.1
组件实现
下面是一个完整的 WangEditor 组件实现,支持图片上传、内容绑定和禁用状态:
<template>
<div class="editor_container">
<Toolbar
:editor="editorRef"
:defaultConfig="toolbarConfig"
class="editor_toolbar"
/>
<Editor
v-model="contentHtml"
:defaultConfig="editorConfig"
:class="{ disabled: disabled, editor_content: true }"
@onChange="doChange"
@onCreated="doCreate"
/>
</div>
</template>
<script>
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { uploadFile } from '@/utils'
import { baseURL } from '@/config'
import store from '@/store'
import { onBeforeUnmount, defineComponent, shallowRef, watch } from 'vue-demi'
import { useRoute } from '@/hooks'
const USER_TOKEN = store.getters['user/token']
export default defineComponent({
name: 'BaseEditor',
components: { Editor, Toolbar },
props: {
value: {
type: String,
default: '',
},
disabled: {
type: Boolean,
default: false,
},
},
setup(props, { emit }) {
const route = useRoute()
const editorRef = shallowRef(null)
const contentHtml = shallowRef('')
const toolbarConfig = {}
const editorConfig = {
placeholder: '请输入内容...',
MENU_CONF: {
uploadImage: {
async customUpload(file, insertFn) {
const { url, name } = await uploadFile(file, route.value.path)
const imgUrl = `${baseURL}/tfle/v1/0/file-preview/by-url?url=${url}&access_token=bearer ${USER_TOKEN}&bucketName=tof`
insertFn(imgUrl, name, imgUrl)
},
},
},
}
watch(
() => props.value,
(value) => {
if (!value) return
contentHtml.value = replaceToken(decodeURIComponent(value))
}
)
watch(() => props.disabled, doDisable, { immediate: true })
const doCreate = (editor) => {
editorRef.value = editor
doDisable(props.disabled)
}
const doChange = (editor) => {
const content = encodeURIComponent(editor.getHtml())
emit('input', content)
emit('change', content)
}
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor === null) return
editor.destroy()
})
function doDisable(value) {
if (value) {
editorRef.value?.disable()
}
}
function replaceToken(html) {
let newHtml = ''
const regex = /\bbearer \b(.*?)\b&bucketName\b/g
const matches = Array.from(new Set(html.match(regex)))
if (!matches.length) {
return html
}
matches.forEach((match) => {
newHtml = html.replaceAll(match, `bearer ${USER_TOKEN}&bucketName`)
})
return newHtml
}
return {
contentHtml,
editorConfig,
editorRef,
toolbarConfig,
doChange,
doCreate,
}
},
})
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style lang="scss" scoped>
.editor_container {
border: 1px solid #ccc;
margin-top: 10px;
height: 500px;
}
.editor_toolbar {
border-bottom: 1px solid #ccc;
}
.editor_content {
border: 1px solid #ccc;
height: 80%;
}
.w-e-full-screen-container {
z-index: 9999 !important;
}
::v-deep {
.disabled {
.w-e-text-container {
background-color: #f5f7fa;
border-color: #dfe4ed;
color: #333;
cursor: not-allowed;
}
}
}
</style>
核心功能解析
1. 组件结构
- Toolbar:编辑器工具栏,包含各种编辑功能按钮
- Editor:编辑器主体,用于输入和显示富文本内容
- 容器:使用
editor_container类包裹,设置边框和高度
2. 配置项
- toolbarConfig:工具栏配置,默认为空对象,使用默认配置
- editorConfig:编辑器配置,包含:
placeholder:占位符文本MENU_CONF:菜单配置,这里主要配置了图片上传
3. 图片上传
使用 customUpload 方法自定义图片上传逻辑:
- 调用
uploadFile函数上传文件,获取返回的url和name - 构建完整的图片访问 URL,包含 baseURL、文件路径、访问令牌和存储桶名称
- 调用
insertFn方法将图片插入到编辑器中
4. 内容绑定
- 使用
v-model绑定contentHtml,实现双向数据绑定 - 监听
props.value的变化,更新编辑器内容 - 监听
doChange事件,将编辑器内容通过emit传递给父组件
5. 禁用状态
- 监听
props.disabled的变化,调用doDisable方法 - 在
doDisable方法中,调用编辑器的disable方法禁用编辑器 - 通过 CSS 样式为禁用状态添加特殊样式
6. 组件销毁
在 onBeforeUnmount 生命周期钩子中,销毁编辑器实例,释放资源
7. Token 替换
replaceToken函数用于替换 HTML 中的令牌,确保图片访问 URL 中的令牌是最新的- 使用正则表达式匹配并替换令牌
使用方法
基本使用
<template>
<div>
<h3>富文本编辑器示例</h3>
<BaseEditor v-model="content" />
<el-button type="primary" @click="submit">提交</el-button>
</div>
</template>
<script>
import BaseEditor from '@/components/BaseEditor'
export default {
components: {
BaseEditor
},
data() {
return {
content: ''
}
},
methods: {
submit() {
console.log('提交内容:', this.content)
// 处理提交逻辑
}
}
}
</script>
禁用状态
<BaseEditor v-model="content" :disabled="true" />
注意事项
-
依赖版本:本文使用的是
@wangeditor/editor@5.0.1和@wangeditor/editor-for-vue@1.0.1,不同版本可能有差异 -
图片上传:需要实现
uploadFile函数来处理文件上传,返回url和name -
令牌管理:需要确保
USER_TOKEN能够正确获取,并且在图片 URL 中正确使用 -
样式冲突:如果遇到样式冲突,可以通过调整 CSS 优先级或使用
::v-deep来解决 -
内存泄漏:确保在组件销毁时调用
editor.destroy()来释放资源 -
Vue 版本:本文适用于 Vue 2.7,使用了
vue-demi来兼容 Vue 2 和 Vue 3 的 API
常见问题
1. 图片上传失败
原因:uploadFile 函数实现不正确,或者后端接口返回格式不符合预期
解决方案:检查 uploadFile 函数的实现,确保它返回正确的 url 和 name
2. 编辑器高度调整
原因:默认高度可能不适合所有场景
解决方案:修改 .editor_container 和 .editor_content 的高度样式
3. 工具栏按钮不显示
原因:可能是工具栏配置问题,或者样式冲突
解决方案:检查 toolbarConfig 配置,确保没有禁用必要的按钮;检查是否有样式冲突
总结
WangEditor 是一款功能强大、易于使用的富文本编辑器,在 Vue 2.7 中使用非常方便。通过本文的介绍,你可以快速实现一个支持图片上传、内容绑定和禁用状态的富文本编辑器组件。
主要功能包括:
- 基本的富文本编辑功能
- 自定义图片上传
- 双向数据绑定
- 禁用状态支持
- 令牌自动替换
希望本文对你在 Vue 2.7 中使用 WangEditor 有所帮助!
技术栈
- 前端框架:Vue 2.7
- 富文本编辑器:WangEditor 5
- 构建工具:Vue CLI / Vite
- 样式:SCSS