vue3使用富文本编辑器

wangEditor V5富文本编辑器

yarn add @wangeditor/editor @wangeditor/editor-for-vue@next

封装公共组件

<template>
  <div>
    <div style="border: 1px solid #ccc; margin-top: 10px">
      <Toolbar
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        style="border-bottom: 1px solid #ccc"
      />
      <Editor
        :defaultConfig="editorConfig"
        v-model="valueHtml"
        style="height: 400px; overflow-y: hidden"
        @onCreated="handleCreated"
        @onChange="handleChange"
        @onDestroyed="handleDestroyed"
        @onFocus="handleFocus"
        @onBlur="handleBlur"
        @customAlert="customAlert"
        @customPaste="customPaste"
      />
    </div>
  </div>
</template>
  
  <script setup>
import "@wangeditor/editor/dist/css/style.css";
import { onBeforeUnmount, ref, shallowRef, onMounted, defineEmits } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { getToken } from "@/utils/auth";
import { ElMessage } from "element-plus";
const props = defineProps(['value'])
const emits = defineEmits(["toparentdata"]);
watch(() => props.value, (val) => {
  //   toRaw(myQuillEditor.value).setHTML(val)
  valueHtml.value = val
  console.log(val, '父组件传的');
}, { deep: true })

// 编辑器实例,必须用 shallowRef,重要!
const editorRef = shallowRef();
// 内容 HTML
const valueHtml = ref("");
// 模拟 ajax 异步获取内容
// onMounted(() => {
//     setTimeout(() => {
//         valueHtml.value = '<p>模拟 Ajax 异步设置内容</p>'
//     }, 1500)
// })
const baseUrl = import.meta.env.VITE_APP_BASE_API;
const headers = ref({ Authorization: "Bearer " + getToken() });

// 菜单内容
const toolbarConfig = {
  excludeKeys: ["blockquote"], //删除的菜单
};
//编辑框内容
const editorConfig = {
  placeholder: "请输入内容...",
  MENU_CONF: {
    // 配置上传图片
    uploadImage: {
      // 请求路径
      server: baseUrl + "/common/upload",
      // // 后端接收的文件名称
      fieldName: "file",
      // maxFileSize: 1 * 1024 * 1024, // 1M
      // // 上传的图片类型
      allowedFileTypes: ["image/*"],
      // // 小于该值就插入 base64 格式(而不上传),默认为 0
      base64LimitSize: 10 * 1024, // 10MB
      // // 自定义插入返回格式【后端返回的格式】
      headers: {
        Authorization: headers.value.Authorization,
      },
      // 将 meta 拼接到 url 参数中,默认 false
      // metaWithUrl: false,
      customInsert (res, insertFn) {
        // JS 语法
        // res 即服务端的返回结果
        // 从 res 中找到 url alt href ,然后插入图片
        insertFn(res.url);
      },
      onBeforeUpload (file) {
        // TS 语法
        // onBeforeUpload(file) {    // JS 语法
        // file 选中的文件,格式如 { key: file }
        return file;

        // 可以 return
        // 1. return file 或者 new 一个 file ,接下来将上传
        // 2. return false ,不上传这个 file
      },

      // 上传进度的回调函数
      onProgress (progress) {
        // progress 是 0-100 的数字
        console.log("progress", progress);
      },

      // 单个文件上传成功之后
      onSuccess (file, res) {
        console.log(`${file.name} 上传成功`, res);
        ElMessage({
          message: `${file.name} 上传成功`,
          type: "success",
        });
      },

      // 单个文件上传失败
      onFailed (file, res) {
        ElMessage.error(`${file.name} 上传失败`);
      },

      // 上传错误,或者触发 timeout 超时
      onError (file, err, res) {
        ElMessage.error(`${file.name} 上传出错`);
      },
    },
  },
};
// 组件销毁时,也及时销毁编辑器,重要!
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) => {
  emits("toparentdata", 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) => {
  // 返回值(注意,vue 事件的返回值,不能用 return)
  // callback(false) // 返回 false ,阻止默认粘贴行为
  callback(true); // 返回 true ,继续默认的粘贴行为
};
const insertText = () => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.insertText("hello world");
};
const printHtml = () => {
  const editor = editorRef.value;
  if (editor == null) return;
  console.log(editor.getHtml());
};
const disable = () => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.disable();
};
  </script>
  

 编辑器工具栏配置

 toolbarConfig: {
        excludeKeys: [
          //隐藏的toolbarKey
          "headerSelect",// 标题
          "blockquote", // 引用
          "bold", // 加粗
          "underline", // 下划线
          "italic", // 斜体
          // 删除线、清除格式等
          "group-more-style",
          {
            key: "group-more-style",
            title: "更多",
            iconSvg:
              '<svg viewBox="0 0 1024 1024"><path d="M204.8 505.6…0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path></svg>',
            menuKeys: Array(5)
          },

          "color", // 文字颜色

          "bgColor", // 背景色

          "fontSize", // 字号

          "fontFamily", // 字体

          "lineHeight", // 行高

          "bulletedList", // 无序列表

          "numberedList", // 有序列表

          "todo", // 代办
          // 对齐
          "group-justify",
          {
            key: "group-justify",
            title: "对齐",
            iconSvg:
              '<svg viewBox="0 0 1024 1024"><path d="M768 793.6v1…72.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>',
            menuKeys: Array(4)
          },
          // 缩进
          "group-indent"
          {
            key: "group-indent",
            title: "缩进",
            iconSvg:
              '<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v1…32h1024v128H0z m0-128V320l256 192z"></path></svg>',
            menuKeys: Array(2)
          },

          "emotion",// 表情

          "insertLink",// 插入链接
          // 上传图片
          {
            key: "group-image",
            title: "图片",
            iconSvg:
              '<svg viewBox="0 0 1024 1024"><path d="M959.877 128…l224.01-384 256 320h64l224.01-192z"></path></svg>',
            menuKeys: Array(2)
          },
          // 上传视频
          {
            key: "group-video",
            title: "视频",
            iconSvg:
              '<svg viewBox="0 0 1024 1024"><path d="M981.184 160….904zM384 704V320l320 192-320 192z"></path></svg>',
            menuKeys: Array(2)
          },

          "insertTable",// 插入表格

          "codeBlock", // 代码块

          "divider", // 分割线

          "undo", // 撤销

          "redo", // 重做

          "fullScreen" // 全屏
          ]
      }

在父组件中使用

        <RichTextEditor
          :value="tbCompanyProfile.detail"
          @toparentdata="toparentdata"
          ref="richEditor"
        />

const toparentdata = (val) => {
  console.log(val.replace(/<p>([^<]*?)<\/p>/gi, '$1'), '--------富文本');
  tbCompanyProfile.value.detail = val
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Argenta99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值