记录在vue3项目中使用wangeditor富文本编译器以及微信小程序中的渲染

发布时间 2023-04-24 09:49:12作者: 万能的李大少

首先,管理后台中的使用

npm install wangeditor

//f封装成了组件,以下是组件中的内容

<template>
    <div style="border: 1px solid #ccc; maxwidth: 600px">
      <!-- 工具栏 -->
      <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="'default'"
      />
      <!-- 内容部分   @onBlur="handleChange"   -->
      <Editor
        style="height: 450px; overflow-y: hidden"
        v-model="props.textHtml"
        :defaultConfig="editorConfig"
        :mode="'default'"
        @onCreated="handleCreated"
        @onChange="handleChange"
     
      />
    </div>
  </template>
  <script setup lang="ts">
  import "@wangeditor/editor/dist/css/style.css"; // 引入 css
 
  import { onBeforeUnmount, shallowRef } from "vue";
  import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
  // import { request } from "@/api/axios";
  import {ajax} from "../../api"
  import { ElMessage } from "element-plus";
  import type { IEditorConfig, IToolbarConfig } from "@wangeditor/core";
  const AJAX_BASE_URL = import.meta.env.VITE_AJAX_BASE_URL
 
  const emits = defineEmits(["getHtmlVal"]);
  const props = defineProps({
    // 内容 HTML
    textHtml: {
      type: String,
      default: "hello",
    },
  });
  console.log('3333',props.textHtml)
  // 编辑器实例,必须用 shallowRef
  const editorRef = shallowRef();
  // 工具栏配置
  const toolbarConfig: Partial<IToolbarConfig> = {
    // 用于去掉不需要的工具栏配置
    excludeKeys: [
      "insertVideo", // 去掉插入视频功能
      "fullScreen", // 去掉全屏功能
      "group-video",   //去掉上传视频

    ],
  };
  // console.log(toolbar.getConfig().toolbarKeys)
  // 编辑器配置
  const editorConfig: Partial<IEditorConfig> = {
    // 最长输入2000字
    maxLength: 2000,
    // 进入页面不自动聚焦
    autoFocus: true,
    MENU_CONF: {},
  };
  // 上传图片
  //@ts-ignore
  editorConfig.MENU_CONF["uploadImage"] = {


    async customUpload(file: any, insertFn: any) {
      upLoadImgVideo("1", file, insertFn);
    },
  };
 
  // 上传视频
  //@ts-ignore
  editorConfig.MENU_CONF["uploadVideo"] = {
    async customUpload(file: any, insertFn: any) {
      upLoadImgVideo("2", file, insertFn);
    },
  };
 
  // 封装 - 上传图片、视频
  const upLoadImgVideo = async (type: string, file: any, insertFn: any) => {
    if (file.size / 1024 / 1024 > 50) {
      ElMessage.error(`文件大小不能超过50MB!`);
      return false;
    } else {
     // 这里根据自己的需求进行处理 --- S
      let formData = new FormData();
      formData.append("uploadFile", file);
      // formData.append("fileType", type);
      const url: string = "/activity/resource/uploadFile";
      console.log(formData)
      //  这里根据自己的需求进行处理 --- E
      const result =await  ajax.post('/file/upload', formData)
      console.log(result)
      if(result.ok  && result.data){
        insertFn( result.data);
      }else{
        ElMessage.warning(`上传失败`);
      }
      
    }
  };
 
  // 组件销毁时,也及时销毁编辑器
  onBeforeUnmount(() => {
    const editor = editorRef.value;
    if (editor == null) return;
    editor.destroy();
  });
 
  const handleCreated = (editor: any) => {
    editorRef.value = editor; // 记录 editor 实例,重要!
    // 查看所有工具栏key
    // console.log(editor.getAllMenuKeys());
  };
  const onClear = ()=>{
    const editor = editorRef.value;
    console.log("fdfd")
    editor.clear()
  }
  const setHtml = (value: any)=>{
    const editor = editorRef.value;
    console.log(value)
    console.log("111",editor.getHtml())

    editor.setHtml(value)
  }
  // 获得输入的内容
  const handleChange = (editor: any) => {
    console.log(editor.getHtml())
    emits("getHtmlVal", editor.getHtml());
  };

  defineExpose({
    onClear,
    setHtml
  });


  </script>
 
  <style lang="scss" scoped>
  :deep() .w-e-textarea-video-container {
    video,
    img {
      max-width: 787px;
    }
  }
  </style>
 
//使用组件
import Editor  from "../../../components/editor/editor.vue";   //引入组件
 
//使用
<Editor @getHtmlVal="getHtmlVal" ref="editor" v-model="goods.description" style="height: 600px" />
//赋值
const getHtmlVal = (value:any)=>{
  console.log(value)
  goods.description = value
}
 
微信小程序中渲染,我用的是rich-text,问题挺多,
第一个问题,小程序不识别缩进问题
result.data.description.replace(/&nbsp;/g,"&ensp;")  //使用ensp替换nbsp
第二个问题,富文本中的图片相连时中间留有空白以及图片宽度的问题
description = description.replace(/<img[^>]*?\s+style=(['"])[^'"]*?\1[^>]*?>/g, function(match) {
       // 将style属性替换为空字符串
      return match.replace(/\s+style=(['"]).*?\1/, '');
 });
 description = description.replace(/<img([^>]*)src=(['"])([^'"]+)\2([^>]*)>/gi, '<img$1src=$2$3$2 style="display:block;width:100%;" catchtap="previewImage" data-src=$2$3$2$4>');
删除原本富文本存在的style,重新添加一个带有样式的style,并且对其添加了一个data-src属性,属性值是当前图片链接,准本对其增加一个预览大图的功能