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

前言:哈喽,大家好,我是码喽的自我修养!今天给大家分享vue3项目中使用富文本编辑器 -- wangEditor,包括wangEditor的下载、安装、使用等等,由浅入深详细讲解!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到带大家,欢迎收藏+关注哦 💕

🌈🌈文章目录

1. wangEditor5介绍

2. 下载 

3. 相关组件

4.了解vue3的shallowRef

使用富文本编辑器的小案例

完整案例--通过富文本编辑器实现文章的编辑并上传至服务器

添加文章的组件代码如下所示

富文本插件组件如下所示

实现效果

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与微信小程序

  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值