1、介绍与最终效果
富文本编辑器主要用于论坛、博客等场景中,用来实现更加丰富的图文展示效果。本文章使用Vue2、Vue3和WangEditor实现这一功能。更多详细配置可到WangEditor官网进行查看。
2、安装依赖
在创建好的Vue2或者Vue3项目中,运行如下命令安装WangEditor富文本编辑器相关依赖
# Vue2 使用这两个命令
yarn add @wangeditor/editor
# 或者 npm install @wangeditor/editor --save
yarn add @wangeditor/editor-for-vue
# 或者 npm install @wangeditor/editor-for-vue --save
# Vue3 使用下面两个命令
yarn add @wangeditor/editor
# 或者 npm install @wangeditor/editor --save
yarn add @wangeditor/editor-for-vue@next
# 或者 npm install @wangeditor/editor-for-vue@next --save
3、在组件中使用
在Vue2中
<script>
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'; // 引入编辑器和工具栏组件
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { uploadFileAPI } from "@/api/commonApi"; // 自定义上传接口
export default {
components: {
Editor,
Toolbar
},
data() {
return {
editor: null,
form: {content: ''},
editorConfig: { placeholder: '请输入内容...' },
mode: 'default', // or 'simple'
}
}
}
</script>
组件中
<template>
<div>
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
></Toolbar>
<Editor
style="height: calc(100vh - 120px); overflow-y: hidden;"
v-model="form.content"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
@onChange="handleChange"
@onFocus="handleFocus"
@onBlur="handleBlur"
@onDestroyed="handleDestroyed"
@customAlert="customAlert"
@customPaste="customPaste"
></Editor>
</div>
</template>
生命周期方法如下
methods: {
onCreated(editor) {
this.editor = Object.seal(editor)
console.log('onCreated', editor)
},
onChange(editor) { console.log('onChange', editor.children) },
onDestroyed(editor) { console.log('onDestroyed', editor) },
onMaxLength(editor) { console.log('onMaxLength', editor) },
onFocus(editor) { console.log('onFocus', editor) },
onBlur(editor) { console.log('onBlur', editor) },
customAlert(info: string, type: string) { window.alert(`customAlert in Vue demo\n${type}:\n${info}`) },
customPaste(editor, event, callback) {
console.log('ClipboardEvent 粘贴事件对象', event)
// const html = event.clipboardData.getData('text/html') // 获取粘贴的 html
// const text = event.clipboardData.getData('text/plain') // 获取粘贴的纯文本
// const rtf = event.clipboardData.getData('text/rtf') // 获取 rtf 数据(如从 word wsp 复制粘贴)
// 自定义插入内容
editor.insertText('xxx')
// 返回 false ,阻止默认粘贴行为
event.preventDefault()
callback(false) // 返回值(注意,vue 事件的返回值,不能用 return)
// 返回 true ,继续默认的粘贴行为
// callback(true)
},
}
在Vue3中
首先引入组件和css文件以及vue相关API、自定义上传接口
<script setup>
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'; // 引入编辑器和工具栏组件
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { uploadFileAPI } from "@/api/commonApi"; // 自定义上传接口
import { onBeforeUnmount, ref, shallowRef, reactive } from 'vue' // 引入vue相关API
let form = reactive({
content: '',
})
let mode = 'default'
</script>
组件中
<template>
<div>
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
></Toolbar>
<Editor
style="height: calc(100vh - 120px); overflow-y: hidden;"
v-model="form.content"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
@onChange="handleChange"
@onFocus="handleFocus"
@onBlur="handleBlur"
@onDestroyed="handleDestroyed"
@customAlert="customAlert"
@customPaste="customPaste"
></Editor>
</div>
</template>
生命周期方法如下
<script setup>
// 编辑器实例,必须用 shallowRef,重要!
const editorRef = shallowRef()
// 内容 HTML
const valueHtml = ref('')
const toolbarConfig = {}
const editorConfig = { placeholder: '请输入内容...', MENU_CONF: {} }
// 组件销毁时,也及时销毁编辑器,重要!
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null) return
editor.destroy()
})
// 编辑器回调函数
const handleCreated = (editor) => {
console.log('created', editor);
editorRef.value = editor // 记录 editor 实例,重要!
}
// 值改变事件
const handleChange = (editor) => {
console.log('change:', editor.getHtml());
}
// 销毁事件
const handleDestroyed = (editor) => {
console.log('destroyed', editor)
}
// 聚焦事件
const handleFocus = (editor) => {
console.log('focus', editor)
}
// 失焦事件
const handleBlur = (editor) => {
console.log('blur', editor)
}
// 自定义提示框
const customAlert = (info, type) => {
alert(`【自定义提示】${type} - ${info}`)
}
const customPaste = (editor, event, callback) => {
console.log('ClipboardEvent 粘贴事件对象', event)
// 自定义插入内容
editor.insertText('xxx')
// 返回值(注意,vue 事件的返回值,不能用 return)
// callback(false) // 返回 false ,阻止默认粘贴行为
callback(true) // 返回 true ,继续默认的粘贴行为
}
</script>
4、自定义图片上传功能
首先安装插件依赖plugin-mention,命令如下
npm i @wangeditor/plugin-mention --save
在js中添加配置
// 自定义图片上传
editorConfig.MENU_CONF['uploadImage'] = {
async customUpload(file, insertFn) {
try {
// 这里结合实际场景写自己上传图片的逻辑,此处代码仅为示例
let res = await uploadFileAPI({file})
// 插入上传的图片url,alt,herf
insertFn(res.data.filePath, 'image', res.data.filePath)
// data.forEach(item => {
// insertFn(item, 'image', item)
// })
} catch (error) {
console.log(error);
}
}
}
除了上述的使用自定义接口实现上传图片功能外,还可以使用插件提供的其他配置项去实现,如下
editorConfig.MENU_CONF['uploadImage'] = {
server: '/api/upload', // 这里写你的服务地址
// 小于该值就插入 base64 格式(而不上传),默认为 0
base64LimitSize: 5 * 1024 // 5kb
}
// 官方提供的基本配置属性
editorConfig.MENU_CONF['uploadImage'] = {
// form-data fieldName ,默认值 'wangeditor-uploaded-image'
fieldName: 'your-custom-name',
// 单个文件的最大体积限制,默认为 2M
maxFileSize: 1 * 1024 * 1024, // 1M
// 最多可上传几个文件,默认为 100
maxNumberOfFiles: 10,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedFileTypes: ['image/*'],
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
meta: {
token: 'xxx',
otherKey: 'yyy'
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: false,
// 自定义增加 http header
headers: {
Accept: 'text/x-json',
otherKey: 'xxx'
},
// 跨域是否传递 cookie ,默认为 false
withCredentials: true,
// 超时时间,默认为 10 秒
timeout: 5 * 1000, // 5 秒
}
5、自定义视频上传功能
原理与图片上传相同,配置项也基本一致,只需要将uploadImage改为uploadVideo,如下
// 自定义图片上传
editorConfig.MENU_CONF['uploadVideo'] = {
async customUpload(file, insertFn) {
try {
// 这里结合实际场景写自己上传图片的逻辑,此处代码仅为示例
let res = await uploadFileAPI({file})
// 插入视频url和poster
insertFn(res.data.filePath, res.data.posterPath)
// data.forEach(item => {
// insertFn(item.url, item.poster)
// })
} catch (error) {
console.log(error);
}
}
}