vue3项目中使用富文本编辑器

前言

适配 Vue3 的富文本插件不多,我看了很多插件官网,也有很多写的非常棒的,有UI非常优雅让人耳目一新的,也有功能非常全面的。
如:

  1. Quill,简单易用,功能全面。
  2. editorjs,UI极其优雅,非常好看。
  3. ckeditor-5,一款完全重写的富文本编辑器,支持现代 Web 标准,例如模块化架构、原生语义化输出等。

还有很多优秀的富文本编辑器插件,就不一一列举了。

可惜这些都只有英文原文档,对于我这样英语阅读能力不是很好的人来说,实在是一种煎熬,当然也是因为周期比较短,没有时间去研究,所以选择了这一款易上手的插件 wangEditor。

推荐原因有二:

  1. wangEditor 有详细的中文文档,以及中文交流环境。因为作者就是国内程序员。
  2. wangEditor 基于 slate 内核开发,但不依赖于 React ,所以它本身无框架依赖。

一、安装

安装 wangeditor 插件

npm install @wangeditor/editor --save
# yarn add @wangeditor/editor

安装 Vue3 组件

npm install @wangeditor/editor-for-vue@next --save
# yarn add @wangeditor/editor-for-vue@next

二、使用

1. 简单使用

这个组件使用起来非常简单,如果只想简单使用,按照下面的实例,即可实现:

<template>
    <div style="border: 1px solid #ccc">
      <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="mode"
      />
      <Editor
        style="height: 500px; overflow-y: hidden;"
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        :mode="mode"
        @onCreated="handleCreated"
      />
    </div>
</template>
<script>
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { onBeforeUnmount, ref, shallowRef } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'

export default {
  components: { Editor, Toolbar },
  setup() {
    // 编辑器实例,必须用 shallowRef
    const editorRef = shallowRef()

    // 内容 HTML
    const valueHtml = ref('')
    const toolbarConfig = {}
    const editorConfig = { placeholder: '请输入内容...' }

    // 组件销毁时,也及时销毁编辑器
    onBeforeUnmount(() => {
        const editor = editorRef.value
        if (editor == null) return
        editor.destroy()
    })

    const handleCreated = (editor) => {
      editorRef.value = editor // 记录 editor 实例,重要!
    }

    return {
      editorRef,
      valueHtml,
      mode: 'default', // 或 'simple'
      toolbarConfig,
      editorConfig,
      handleCreated
    };
  }
}
</script>  

以上,即可实现最简单的富文本编辑功能,valueHtml 就是富文本编辑的内容,只需要使用 v-html 指令即可将其渲染。

2. 配置菜单栏

上面的实例很多功能不完善,只有最原始的功能,如果需要更加丰富的功能,需要对菜单栏进行自定义编辑。

<template>
    <div class="edit">
      <Toolbar class="Toolbar" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
      <Editor class="Editor" :defaultConfig="editorConfig" :mode="mode" v-model="valueHtml" @onCreated="handleCreated" @customPaste="customPaste" />
    </div>
</template>

三、自定义图片\视频上传功能

自带图片上传功能文档

自带的图片、视频上传服务可能无法 适用与真实的开发场景,所以对这一块的功能进行自定义是必然的。

在同一页面公共地方写 editorConfig.MENU_CONF['uploadImage'] 方法,上传图片、视频时会自动触发,可以同时选择多张照片上传,图片会一张一张上传。

// 自定义图片上传
editorConfig.MENU_CONF['uploadImage'] = {
	async customUpload(file, insertFn) {
		let formData = new FormData();
		formData.append('files', file);
		try {
			// 这里结合实际场景写自己上传图片的逻辑,此处代码仅为示例
			const { data } = await upload(formData);
			// 对图片进行处理,同样需要结合实际场景
			data.forEach(item => {
				insertFn(item, 'image', item)
			})
		} catch (error) {
			console.log(error);
		}
	}
}

// 自定义视频上传
editorConfig.MENU_CONF['uploadVideo'] = {
	async customUpload(file, insertFn) {
		let formData = new FormData();
		formData.append('files', file);
		try {
			// 这里结合实际场景写自己上传图片的逻辑,此处代码仅为示例
			const { data } = await upload(formData);
			// 对图片进行处理,同样需要结合实际场景
			data.forEach(item => {
				insertFn(item, 'video')
			})
		} catch (error) {
			console.log(error);
		}
	}
}

注意

  1. 图片无法控制具体宽度,只能按照比例确定宽度
  2. 图片默认为自身100%宽度,如需限制,可以在盒子外层使用 !important

常见错误

  1. vue-router.mjs:3471 Error: Module build failed (from ./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js): TypeError: Cannot read property 'content' of null
    在这里插入图片描述
    可能是 vue-loader 版本有问题,较低或较高都有可能;也有可能是写法有问题,建议仔细检查代码,这个问题在 ts 中很容易出现。

四、复制粘贴功能

这个功能原本就有,默认会携带格式,如需去除,可以对齐进行修改和限制。以下示例为粘贴纯文本,如果更多限制,可以自行改写。

const customPaste = (editor, event, callback) => {
	const text = event.clipboardData.getData('text/plain') // 获取粘贴的纯文本
	if (text) {
		editor.insertText(text)
		event.preventDefault()
		callback(false)
	}
}

如需作者补充或修改,欢迎在评论区留言。
END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/177330.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

什么是视频直播美颜SDK?美颜SDK对比评测与实战应用

为了满足用户对于高质量美颜的需求&#xff0c;各种美颜技术应运而生&#xff0c;其中最为关键的工具之一就是视频直播美颜SDK。 一、视频直播美颜SDK简介 美颜SDK专注于提供实时美颜效果&#xff0c;使得在视频直播过程中能够实现肤色均匀、磨皮、瘦脸等效果&#xff0c;提高…

安卓手机termux上安装MariaDB数据库并实现公网环境下的远程连接

文章目录 前言1.安装MariaDB2.安装cpolar内网穿透工具3. 创建安全隧道映射mysql4. 公网远程连接5. 固定远程连接地址 前言 Android作为移动设备&#xff0c;尽管最初并非设计为服务器&#xff0c;但是随着技术的进步我们可以将Android配置为生产力工具&#xff0c;变成一个随身…

飞书CEO谢欣:绝大部分企业希望拥抱AI,但并未做好准备

11月22日&#xff0c;飞书在北京举办了产品发布会&#xff0c;正式发布“飞书智能伙伴”等系列AI产品。“飞书智能伙伴”有知识、有记忆&#xff0c;有主动性&#xff0c;也能深入到业务中。在内容创作、内容总结、数据分析、场景构建、系统搭建等业务场景&#xff0c;用户均可…

c语言编程(模考1)代码

计算1-10之间数的乘积 #include<stdio.h> int main(){int i;long sum 1;for(i1;i<10;i)sum sum*i;printf("the sum of add is %ld",sum);} 运行结果 从键盘输入两个数&#xff0c;求出最大值&#xff08;要求使用函数完成求最大值&#xff0c;并且用…

【考研数学】数学一“背诵”手册(一)| 高数部分(2)

文章目录 引言一、高数级数空间解析几何球坐标变换公式零碎公式 写在最后 引言 高数一篇文章还是写不太下&#xff0c;再分一些到这里来吧 一、高数 级数 阿贝尔定理&#xff1a;若级数 ∑ a n x n \sum a_nx^n ∑an​xn 当 x x 0 xx_0 xx0​ 时收敛&#xff0c;则适合不…

Python配置与测试利器:Hydra + pytest的完美结合

简介&#xff1a;Hydra 和 pytest 可以一起使用&#xff0c;基于 Hydra Pytest 的应用可以轻松地管理复杂配置&#xff0c;并编写参数化的单元测试&#xff0c;使得Python开发和测试将变得更为高效。 安装&#xff1a; pip install hydra-core pytest案例源码&#xff1a;my…

【计算方法与科学建模】矩阵特征值与特征向量的计算(三):Householder方法及其Python实现

文章目录 一、Jacobi 旋转法二、Jacobi 过关法三、Householder 方法1. 旋转变换a. 旋转变换的选择b. 旋转变换的顺序 2. Householder矩阵&#xff08;Householder Matrix&#xff09;a. H矩阵的定义b. H变换的几何解释c. H变换的应用场景 3. H变换过程详解a. 过程介绍b. 细节解…

IPFoxy:什么是数据中心代理IP?好用吗?

数据中心代理是代理IP中最常见的类型&#xff0c;也被称为机房IP。这些代理服务器为用户分配不属于 ISP&#xff08;互联网服务提供商&#xff09;而来自第三方云服务提供商的 IP 地址。数据中心代理的最大优势——它们允许在访问网络时完全匿名。 如果你正在寻找海外代理IP&am…

华为昇腾开发板共享Windows网络上网的方法

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 具体参考文章&#xff1a;linux(内网&#xff09;通过window 上网。具体是两步&#xff1a;一是在windows上设置internet连接共享。二是打开Atlas 200I D…

毕业设计2349基于jsp的网上订餐系统【程序源码+文档+调试运行】

摘要 本文介绍了一个网上订餐系统的设计与实现。该系统分为前台用户模块和后台管理员模块&#xff0c;具有用户注册/登录、网站公告、菜品中心、购物车、用户后台、留言板等功能。管理员可以对用户信息、网站公告、菜品类别、菜品信息、订单信息、菜品评价信息、留言板信息和支…

对比多家互联网医院系统技术代码:数字医疗服务的背后

1. 在线问诊模块 1.1 A医疗系统 A医疗系统采用WebSocket实现实时通信&#xff0c;使用Node.js和Socket.io来建立WebSocket连接&#xff1a; // 服务器端 Node.js 代码 const express require(express); const http require(http); const socketIo require(socket.io);const…

编译QT Mysql库并集成使用

安装MSVC编译器与Windows 10 SDK 打开Visual Studio Installer&#xff0c;如果已经安装过内容了可能是如下页面&#xff0c;点击修改&#xff08;头一回打开的话不需要这一步&#xff09;&#xff1a; 然后在工作负荷中勾选使用C的桌面开发&#xff0c;它会帮我们勾选好一些…

一篇文章教你Pytest快速入门和基础讲解,一定要看!

前言 目前有两种纯测试的测试框架&#xff0c;pytest和unittest unittest应该是广为人知&#xff0c;而且也是老框架了&#xff0c;很多人都用来做自动化&#xff0c;无论是UI还是接口 pytest是基于unittest开发的另一款更高级更好用的单元测试框架 出去面试也好&#xff0c;跟…

DDoS攻击频发,科普防御DDoS攻击的几大有效方法

谈到目前最凶猛、频率高&#xff0c;且令人深恶痛绝的网络攻击&#xff0c;DDoS攻击无疑能在榜上占有一席之地。各种规模的企业报包括组织机构都可能受到影响&#xff0c;它能使企业宕机数小时以上&#xff0c;给整个互联网造成无数损失。可以说&#xff0c;怎样防御DDoS攻击是…

【鸿蒙应用ArkTS开发系列】- 云开发入门实战二 实现城市多级联动Demo(上)

目录 概述 云数据库开发 一、创建云数据库的对象类型。 二、预置数据&#xff08;为对象类型添加数据条目&#xff09;。 三、部署云数据库 云函数实现业务逻辑 一、创建云函数 二、云函数目录讲解 三、创建resources目录 四、获取云端凭据 五、导出之前创建的元数据…

【endnote】如何将参考文献放到想放的位置

1. 方式 直接将生成的文献全选拖到想放的位置 注意&#xff1a;不要使用ctrlx这种操作。 2.具体操作 2.1 新建测试文档 如下图&#xff1a; 2.2 引用两篇文献】 如下图&#xff1a; 2.3 测试 如下图&#xff0c;选中所有已经引用的文献。 拖拽到想要防止的位置。 新…

JavaFx学习问题3---Jar包路径问题 (疑难杂症)

文章目录 前置提要:解决方法:调试JAR包后续补充&#xff1a; 前置提要: 我做了的JavaFx程序中&#xff0c;需要通过一个文件夹的相对路径&#xff0c;获取文件夹下所有音频文件的路径&#xff0c;把这些路径字符串放到一个List集合里&#xff0c;然后用Media让它播放声音。问题…

周报6_YMK

周报6 本周主要在看代码&#xff1a;看Medusa头的代码发现不是很了解base_model那部分&#xff0c;所以又去看了llama2的代码和一些相关博客。 重写了一部分佛山中医学院项目的代码&#xff0c;更规范一些。 调研CosmoFlow&#xff0c;是一个深度学习预测宇宙参数的模型&…

git中的分支管理:git branch,git checkout,解决git中的分支冲突的方法【Git学习三】

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;Git等软件工具技术的使用 &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要…

【亚太杯思路助攻】2023年第十三届APMCM亚太地区大学生数学建模竞赛——(文末领取方式)

2023年第十三届APMCM亚太地区大学生数学建模竞赛——来啦&#xff01;&#xff01;&#xff01; 大家准备好了吗&#xff1f;别担心&#xff0c;【数模加油站】会像数模国赛、研赛一样&#xff0c;第一时间提供无偿解题思路、代码、参考文献等资料帮助大家。 祝各位小伙伴都能…