wangeditor 富文本 使用及 上传本地图片的方法

文章标题:Vue组件实现富文本编辑器

文章摘要:本文介绍了如何使用Vue和Wangeditor插件实现富文本编辑器组件,并详细解释了组件中的各个部分和功能。

Vue组件实现富文本编辑器 在Web开发中,富文本编辑器是一个非常常见的功能,它能够让用户以所见即所得的方式编辑和排版文本内容。本文将介绍如何使用Vue和Wangeditor插件实现一个富文本编辑器组件。

  1. 安装依赖 首先,我们需要安装@wangeditor/editor-for-vue插件,该插件提供了与Vue集成的富文本编辑器组件。可以通过以下命令来安装:

npm install @wangeditor/editor-for-vue

  1. 创建富文本编辑器组件 在Vue项目中,创建一个名为RichTextEditor的组件,用于展示富文本编辑器界面和处理相关逻辑。

组件模板代码如下:

html 复制代码
<template>
  <div v-if="newVisible">
    <div class="container"></div>
    <div style="border: 1px solid #ccc">
      <!-- 工具栏 -->

      <Toolbar
        :editor="editorRef"
        style="border-bottom: 1px solid #ccc"
        :defaultConfig="toolbarConfig"
      />
      <!-- 编辑器 -->
      <Editor
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        style="height: 500px; overflow-y: hidden"
        @onCreated="handleCreated"
      />
    </div>
    <div class="btn-container">
      <CBotton type="primary" @click="save">保存</CBotton>
      <CBotton type="dashed" @click="cancel">取消</CBotton>
    </div>
  </div>
</template>

在上述代码中,我们通过v-if指令控制编辑器组件的显示和隐藏。组件包含一个工具栏和一个编辑器,并在底部添加了保存和取消按钮。

  1. 定义组件的数据和方法在标签中,我们需要定义组件的数据和方法。首先,引入所需的依赖:
javascript 复制代码
<script setup>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { uploadFile } from "@/api/base";
import { submitUploadInfoApi, getHelpContent } from "@/api/sale/help-set.ts";
import { message } from "ant-design-vue";
import {
  onBeforeUnmount,
  shallowRef,
  defineProps,
  ref,
  computed,
  defineEmits,
  reactive,
  watch,
} from "vue";
</script>
接着,定义组件需要的数据和方法:

javascript
// 编辑器实例,必须用 shallowRef,重要!
const editorRef = shallowRef();
const photoGalleryDialogVisible = ref();
const spinning = ref(false);

// 内容 HTML
const valueHtml = ref("");

const props = defineProps({
  visible: { type: Boolean, default: false },
  info: { type: Object, default: null },
  content: { type: Object, default: null },
});
const emit = defineEmits(["confirm", "update:visible", "select"]);

const newVisible = computed({
  get() {
    // 传过来的一行
    return props.visible;
  },
});

watch(
  () => props.visible,
  (val) => {
    console.log("val: ", props.info);
    if (val) {
      if (props?.content?.content) {
        valueHtml.value = props.content.content;
      }
    } else {
    }
  }
);

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

const save = async () => {
  // 保存逻辑
  const p = {
    categoryId: props.info.id,
    contentType: 1,
    content: valueHtml.value,
  };
  const res = await submitUploadInfoApi(p);
  if (res.code == 0) {
    cancel();
    emit("select", props.info.id);
    return message.success(res.msg);
  }
};

const cancel = () => {
  // 取消逻辑
  console.log("取消编辑");
  emit("update:visible", false);
  valueHtml.value = "";
};

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

在上述代码中,我们使用了Vue 3中的Composition API来定义组件的数据和方法。其中,editorRef用于保存编辑器实例,valueHtml用于存储编辑器中的HTML内容。

save方法用于保存编辑的内容,首先将内容发送到后端进行保存,并在保存成功后触发select事件。cancel方法用于取消编辑操作,清空内容并隐藏编辑器。

最后,我们使用onBeforeUnmount钩子函数,在组件销毁前及时销毁编辑器实例。

  1. 配置工具栏和编辑器 在上述代码中,我们还需要配置编辑器的工具栏和编辑器本身的相关属性。代码如下:
javascript 复制代码
<script setup>
// 工具栏配置
const toolbarConfig = {
  toolbarKeys: [
    // 一些常用的菜单 key
    "bold", // 加粗
    "italic", // 斜体
    "through", // 删除线
    "underline", // 下划线
    "bulletedList", // 无序列表
    "numberedList", // 有序列表
    "color", // 文字颜色
    "fontSize", // 字体大小
    "lineHeight", // 行高
    "uploadImage", // 上传图片
    "delIndent", // 缩进
    "indent", // 增进
    "deleteImage", //删除图片
    "divider", // 分割线
    "justifyCenter", // 居中对齐
    "justifyJustify", // 两端对齐
    "justifyLeft", // 左对齐
    "justifyRight", // 右对齐
    "undo", // 撤销
    "redo", // 重做
    "clearStyle", // 清除格式
  ],
};

// 编辑器配置
const editorConfig = {
  placeholder: "",
  MENU_CONF: {
    uploadImage: {
      server: uploadFile.url,
      headers: { Authorization: uploadFile.Authorization },
      "tenant-id": "1",
      fieldName: "file",
      customInsert(res, insertFn) {
        if (res.code == 0) {
          insertFn(res.data, null, res.data);
        }
      },
    },
  },
};
</script>

在上述代码中,我们通过toolbarConfig配置对象定义了工具栏的显示菜单,包括加粗、斜体、删除线、下划线、无序列表、有序列表、文字颜色、字体大小、行高、上传图片等功能。

editorConfig用于配置编辑器的相关属性,包括占位符文本(placeholder)以及上传图片的配置。

  1. 添加样式 最后,在组件的标签中,我们可以添加一些样式来美化富文本编辑器的界面。例如:
html 复制代码
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style>
.btn-container {
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  margin-top: 60px;
}
.container {
  display: flex;
  justify-content: center;
  align-items: center;
}

h1 {
  text-align: center;
  font-size: 28px;
}
</style>

以上代码中,我们引入了Wangeditor默认的样式文件,并自定义了一些样式来调整按钮容器和编辑器容器的布局。

  1. 使用富文本编辑器组件 完成以上步骤后,我们就可以在其他Vue组件中使用RichTextEditor组件了。例如:
html 复制代码
        <Editor
            v-show="onsitesVisible"
            :info="onsiteActive"
            :content="content"
            v-model:visible="onsitesVisible"
            @confirm="getLists"
            @select="selects"
          />

在上述代码中,我们将RichTextEditor组件作为子组件引入,并通过:visible、:info和:content属性来传递组件需要的参数。同时,可以监听select事件来处理富文本编辑器中的选中操作。

结语 在本文中,我们介绍了如何使用Vue和Wangeditor插件实现一个富文本编辑器组件,并详细解释了组件中的各个部分和功能。通过这个组件,用户可以方便地进行富文本内容的编辑和排版。希望本文能对你理解和使用富文本编辑器有所帮助!

完整代码

html 复制代码
<template>
  <div v-if="newVisible">
    <div class="container"></div>
    <div style="border: 1px solid #ccc">
      <!-- 工具栏 -->

      <Toolbar
        :editor="editorRef"
        style="border-bottom: 1px solid #ccc"
        :defaultConfig="toolbarConfig"
      />
      <!-- 编辑器 -->
      <Editor
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        style="height: 500px; overflow-y: hidden"
        @onCreated="handleCreated"
      />
    </div>
    <div class="btn-container">
      <CBotton type="primary" @click="save">保存</CBotton>
      <CBotton type="dashed" @click="cancel">取消</CBotton>
    </div>
  </div>
</template>
<script setup>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { uploadFile } from "@/api/base";
import { submitUploadInfoApi, getHelpContent } from "@/api/sale/help-set.ts";
import { message } from "ant-design-vue";
import {
  onBeforeUnmount,
  shallowRef,
  defineProps,
  ref,
  computed,
  defineEmits,
  reactive,
  watch,
} from "vue";

// 编辑器实例,必须用 shallowRef,重要!
const editorRef = shallowRef();
const photoGalleryDialogVisible = ref();
const spinning = ref(false);

// 内容 HTML
const valueHtml = ref("");

const props = defineProps({
  visible: { type: Boolean, default: false },
  info: { type: Object, default: null },
  content: { type: Object, default: null },
});
const emit = defineEmits(["confirm", "update:visible", "select"]);

const newVisible = computed({
  get() {
    // 传过来的一行
    return props.visible;
  },
});
watch(
  () => props.visible,
  (val) => {
    console.log("val: ", props.info);
    if (val) {
      if (props?.content?.content) {
        valueHtml.value = props.content.content;
      }
    } else {
    }
  }
);
const handleCreated = (editor) => {
  editorRef.value = editor; // 记录 editor 实例,重要!
};
const save = async () => {
  // 保存逻辑
  const p = {
    categoryId: props.info.id,
    contentType: 1,
    content: valueHtml.value,
  };
  const res = await submitUploadInfoApi(p);
  if (res.code == 0) {
    cancel();
    emit("select", props.info.id);
    return message.success(res.msg);
  }
};

const cancel = () => {
  // 取消逻辑
  console.log("取消编辑");
  emit("update:visible", false);
  valueHtml.value = "";
};

// 组件销毁时,及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});
// 工具栏配置
const toolbarConfig = {
  toolbarKeys: [
    // 一些常用的菜单 key
    "bold", // 加粗
    "italic", // 斜体
    "through", // 删除线
    "underline", // 下划线
    "bulletedList", // 无序列表
    "numberedList", // 有序列表
    "color", // 文字颜色
    "fontSize", // 字体大小
    "lineHeight", // 行高
    "uploadImage", // 上传图片
    "delIndent", // 缩进
    "indent", // 增进
    "deleteImage", //删除图片
    "divider", // 分割线
    "justifyCenter", // 居中对齐
    "justifyJustify", // 两端对齐
    "justifyLeft", // 左对齐
    "justifyRight", // 右对齐
    "undo", // 撤销
    "redo", // 重做
    "clearStyle", // 清除格式
  ],
};
// 编辑器配置

const editorConfig = {
  placeholder: "",
  MENU_CONF: {
    uploadImage: {
      server: uploadFile.url,
      headers: { Authorization: uploadFile.Authorization },
      "tenant-id": "1",
      fieldName: "file", // 这里有个坑,如果返回的响应结果是没有上传文件,跟这里关系很大
      customInsert(res, insertFn) {
        if (res.code == 0) {
          insertFn(res.data, null, res.data);
        }
      },
    },
  },
};
</script>

<!-- 别忘了引入样式 -->
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style>
.btn-container {
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  margin-top: 60px;
}
.container {
  display: flex;
  justify-content: center;
  align-items: center;
}

h1 {
  text-align: center;
  font-size: 28px;
}
</style>
相关推荐
优雅永不过时·25 分钟前
Three.js 原生 实现 react-three-fiber drei 的 磨砂反射的效果
前端·javascript·react.js·webgl·threejs·three
神夜大侠3 小时前
VUE 实现公告无缝循环滚动
前端·javascript·vue.js
明辉光焱3 小时前
【Electron】Electron Forge如何支持Element plus?
前端·javascript·vue.js·electron·node.js
柯南二号3 小时前
HarmonyOS ArkTS 下拉列表组件
前端·javascript·数据库·harmonyos·arkts
wyy72933 小时前
v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条
前端·ui·html
前端郭德纲4 小时前
ES6的Iterator 和 for...of 循环
前端·ecmascript·es6
王解4 小时前
【模块化大作战】Webpack如何搞定CommonJS与ES6混战(3)
前端·webpack·es6
欲游山河十万里4 小时前
(02)ES6教程——Map、Set、Reflect、Proxy、字符串、数值、对象、数组、函数
前端·ecmascript·es6
明辉光焱4 小时前
【ES6】ES6中,如何实现桥接模式?
前端·javascript·es6·桥接模式
PyAIGCMaster4 小时前
python环境中,敏感数据的存储与读取问题解决方案
服务器·前端·python