前言:哈喽,大家好,我是码喽的自我修养!今天给大家分享vue3项目中使用富文本编辑器 -- wangEditor,包括wangEditor的下载、安装、使用等等,由浅入深详细讲解!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到带大家,欢迎收藏+关注哦 💕
🌈🌈文章目录
1. wangEditor5介绍
wangEditor5 —— 轻量级 web 富文本编辑器,配置方便,使用简单。支持 IE10+ 浏览器。 官网:www.wangEditor.com
2. 下载
注意: wangeditor都是小写字母
// 下面两个依赖都需要安装
npm i @wangeditor/editor
npm i @wangeditor/editor-for-vue@next
3. 相关组件
Editor : 编辑器组件
Toolbar: 菜单栏组件
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
...
<template>
<div style="border: 1px solid #ccc">
<Toolbar 属性/>
<Editor 属性/>
</div>
</template>
4.了解vue3的shallowRef
Vue 的响应性系统默认是深度的。虽然这让状态管理变得更直观,但在数据量巨大时,深度响应性也会导致不小的性能负担,因为每个属性访问都将触发代理的依赖追踪。 Vue 确实也为此提供了一种解决方案,通过使用 shallowRef() 和 shallowReactive() 来绕开深度响应。浅层式 API 创建的状态只在其顶层是响应式的,对所有深层的对象不会做任何处理。
const shallowArray = shallowRef([
/* 巨大的列表,里面包含深层的对象 */
])
// 这不会触发更新...
shallowArray.value.push(newObject)
// 这才会触发更新
shallowArray.value = [...shallowArray.value, newObject]
// 这不会触发更新...
shallowArray.value[0].foo = 1
// 这才会触发更新
shallowArray.value = [
{
...shallowArray.value[0],
foo: 1
},
...shallowArray.value.slice(1)
]
使用富文本编辑器的小案例
<script setup>
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { onBeforeUnmount, shallowRef, computed } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
//接收props
const props = defineProps({
html: String,
});
const emit = defineEmits();
// 内容 HTML
const valueHtml = computed({
get: () => {
return props.html;
},
set: (value) => {
emit("update:html", value);
},
});
//定义模式
const mode = "default"; // 或 'simple'
// 默认按模式来显示工具栏
const toolbarConfig = {};
//配置上传图片的接口
// 初始化默认配置
const editorConfig = {
placeholder: "请输入内容...",
MENU_CONF: {},
};
editorConfig.MENU_CONF["uploadImage"] = {
server: "/api/upload",
fieldName: "file",
headers: {
Authorization: "Bearer " + sessionStorage.getItem("token"),
},
// 上传之前触发
onBeforeUpload(file) {
return file;
},
// 上传进度的回调函数
onProgress(progress) {
// onProgress(progress) {
// progress 是 0-100 的数字
console.log("progress", progress);
},
// 自定义插入图片
customInsert(res, insertFn) {
// customInsert(res, insertFn) {
// res 即服务端的返回结果
let { url } = res;
// 从 res 中找到 url alt href ,然后插入图片
insertFn(url);
},
};
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
const handleCreated = (editor) => {
editorRef.value = editor; // 记录 editor 实例,重要!
//打印所有默认配置
// console.log(editor.getConfig()["MENU_CONF"])
};
</script>
<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>
<style lang="scss" scoped></style>
实现效果如下图所示
完整案例--通过富文本编辑器实现文章的编辑并上传至服务器
添加文章的组件代码如下所示
<script setup>
import { ref } from "vue";
import Editor from "./editor.vue";
import { _AddNews } from "../../api/news.js";
const ruleForm = ref({
title: "",
author: "",
content: "",
});
const html = ref("");
const form = ref(null);
// 提交按钮
const submitForm = async () => {
ruleForm.value.content = html.value;
// console.log(ruleForm.value);
// 可以得到组件中写的title和 作者和 内容 而后发起请求传递到数据库
let res = await _AddNews(ruleForm.value);
let { code } = res.data;
if (code === 0) {
alert("添加成功");
resetForm();
}
};
// 重置按钮
const resetForm = () => {
// 配置html的内容为空 清空富文本编辑器中的内容
html.value = "";
ruleForm.value = [];
};
</script>
<template>
<div class="add-news">
<el-form ref="form" :model="ruleForm" status-icon>
<!-- 新闻标题 -->
<el-form-item label="新闻标题" prop="title" class="width">
<el-input v-model="ruleForm.title" />
</el-form-item>
<!-- 作者 -->
<el-form-item label="新闻作者" prop="author" class="width">
<el-input v-model="ruleForm.author" />
</el-form-item>
<el-form-item label="文章内容" prop="content" class="text">
<!-- 富文本编辑器组件 -->
<Editor v-model:html="html"></Editor>
</el-form-item>
</el-form>
<el-form-item class="right">
<el-button type="primary" @click="submitForm(form)"> 提交 </el-button>
<el-button @click="resetForm(form)">重置</el-button>
</el-form-item>
</div>
</template>
<style lang="scss" scoped>
.add-news {
display: flex;
align-items: baseline;
margin-top: 30px;
.right {
margin-left: -134px;
}
}
.width {
width: 500px;
margin-left: 20px;
}
.text {
width: 1400px;
}
</style>
富文本插件组件如下所示
<script setup>
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { onBeforeUnmount, shallowRef, computed } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
//接收props
const props = defineProps({
html: String,
});
const emit = defineEmits();
// 内容 HTML
const valueHtml = computed({
get: () => {
return props.html;
},
set: (value) => {
emit("update:html", value);
},
});
//定义模式
const mode = "simple"; // 或 'simple'
// 默认按模式来显示工具栏
const toolbarConfig = {};
//配置上传图片的接口
// 初始化默认配置
const editorConfig = {
placeholder: "请输入内容...",
MENU_CONF: {},
};
editorConfig.MENU_CONF["uploadImage"] = {
server: "/api/upload",
fieldName: "file",
headers: {
Authorization: "Bearer " + sessionStorage.getItem("token"),
},
// 上传之前触发
onBeforeUpload(file) {
return file;
},
// 上传进度的回调函数
onProgress(progress) {
// onProgress(progress) {
// progress 是 0-100 的数字
console.log("progress", progress);
},
// 自定义插入图片
customInsert(res, insertFn) {
// customInsert(res, insertFn) {
// res 即服务端的返回结果
let { url } = res;
// 从 res 中找到 url alt href ,然后插入图片
insertFn(url);
},
};
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
const handleCreated = (editor) => {
editorRef.value = editor; // 记录 editor 实例,重要!
//打印所有默认配置
// console.log(editor.getConfig()["MENU_CONF"])
};
</script>
<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>
<style lang="scss" scoped></style>
实现效果
🚀 个人简介:某大型国企高级前端开发工程师,7年研发经验,信息系统项目管理师、CSDN优质创作者、阿里云专家博主,华为云云享专家,分享前端后端相关技术与工作常见问题~
💟 作 者:码喽的自我修养❣️
📝 专 栏:vue从基础到起飞🌈 若有帮助,还请 关注➕点赞➕收藏 ,不行的话我再努努力💪💪💪
更多专栏订阅推荐:
👍 前端工程搭建
💕 javaScript深入研究✍️ GIS地图与大数据可视化
✈️ HTML5与CSS3
⭐️ uniapp与微信小程序