vue3封装wangEditor 富文本 包含图片上传

  1. 下载并安装
yarn add @wangeditor/editor
# 或者 npm install @wangeditor/editor --save
 
yarn add @wangeditor/editor-for-vue@next
# 或者 npm install @wangeditor/editor-for-vue@next --save

2.在项目components文件夹新建quill.vue 文件,名字可以自定义 

<template>
  <div style="border: 1px solid #ccc">
    <Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" />
    <Editor style="min-height: 300px" v-model="valueHtml" :defaultConfig="editorConfig" @onCreated="handleEditorCreated" />
  </div>
</template>
<script lang="js">
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { ref, shallowRef, watchEffect } from "vue";
import { getToken } from "@/utils/auth";
export default {
  components: {
    Editor,
    Toolbar
  },
  props: {
    value: String
  },
  emits: ["update:value"],
  setup(props, { emit }) {
    // 编辑器实例,必须用 shallowRef

    const editorRef = shallowRef(null);

    // 内容 HTML
    const valueHtml = ref(props.value || "");

    // 配置功能栏
    const toolbarConfig = {
      toolbarKeys: [
        "headerSelect",
        "blockquote",
        "|",
        "bold",
        "underline",
        "italic",
        {
          key: "group-more-style",
          title: "更多",
          iconSvg:
              "<svg viewBox=\"0 0 1024 1024\"><path d=\"M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z\"></path><path d=\"M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z\"></path><path d=\"M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z\"></path></svg>",
          menuKeys: ["through", "code", "sup", "sub"]
        },
        "color",
        "bgColor",
        "|",
        "fontSize",
        {
          key: "group-justify",
          title: "对齐",
          iconSvg:
              "<svg viewBox=\"0 0 1024 1024\"><path d=\"M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z\"></path></svg>",
          menuKeys: ["justifyLeft", "justifyRight", "justifyCenter", "justifyJustify"]
        },
        "todo",
        "fontFamily",
        {
          key: "group-indent",
          title: "缩进",
          iconSvg:
              "<svg viewBox=\"0 0 1024 1024\"><path d=\"M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z\"></path></svg>",
          menuKeys: ["indent", "delIndent"]
        },
        "|",
        "emotion",
        "insertLink",
        "uploadImage",
        "insertTable",
        "codeBlock",
        "divider",
        "clearStyle",
        "|",
        "undo",
        "redo"
      ]
    };

    // 编辑器配置
    const editorConfig = {
      placeholder: "请输入内容...",
      // 所有的菜单配置,都要在 MENU_CONF 属性下
      MENU_CONF: {}
    };

    const handleEditorCreated = (editor) => {
      editorRef.value = editor; // 记录 editor 实例,重要!
      console.log("created", editor);
    };
    watchEffect(() => {
      valueHtml.value = props.value;
    });
    watchEffect(() => {
      emit("update:value", valueHtml.value);
    });

    const handleChange = (editor) => {
      console.log("change:", editor.children);
    };
    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) => {
      console.log("ClipboardEvent 粘贴事件对象", event);
      // const html = event.clipboardData.getData('text/html') // 获取粘贴的 html
      // const text = event.clipboardData.getData('text/plain') // 获取粘贴的纯文本
      // const rtf = event.clipboardData.getData('text/rtf') // 获取 rtf 数据(如从 word wsp 复制粘贴)

      // 自定义插入内容
      editor.insertText("xxx");

      // 返回 false ,阻止默认粘贴行为
      event.preventDefault();
      callback(false); // 返回值(注意,vue 事件的返回值,不能用 return)

      // 返回 true ,继续默认的粘贴行为
      // callback(true)
    };

    // 父组件调用子组件的方法清空编辑器内容
    const abc = function() {
      valueHtml.value = "";
    };



    editorConfig.MENU_CONF["uploadImage"] = {
      // 自定义上传图片 方法
      server: "/api/upload/fastDfs/uploadImage",
      uploadImgMaxLength: 9,
      maxFileSize: 15 * 1024 * 1024, // 单个文件的最大体积限制,默认为 5M
      fieldName: "file",
      meta: {
        // source: "sys_user_guide"
      },
      headers: {
        // clientType: 0,
        Authorization: getToken()
      },
      customInsert(res, insertFn) {
        insertFn(res.data[0].path, "", "");
      }
    };

    return {
      editorRef,
      valueHtml,
      mode: "default", // 或 'simple'
      toolbarConfig,
      editorConfig,
      handleEditorCreated,
      handleChange,
      handleDestroyed,
      handleFocus,
      handleBlur,
      customAlert,
      customPaste,
      abc
    };
  }
};
</script>

3. 父页面引入使用

<template> 
<Quill :value="editorContent" @update:value="handleEditorUpdate"></Quill>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, toRaw } from "vue";
const formState = reactive({
  msgContent: ""
});
import Quill from "@/components/quill/index.vue";
const editorContent = ref("");
const handleEditorUpdate = (value:any) => {
  formState.msgContent = value;
};
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值