Browse Source

feat: `wangeditor`富文本添加多个富文本和自定义图片上传示例

xiaoxian521 1 year ago
parent
commit
82e994434a

+ 56 - 0
src/views/editor/components/base.vue

@@ -0,0 +1,56 @@
+<script setup lang="ts">
+import "@wangeditor/editor/dist/css/style.css";
+import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
+import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue";
+
+defineOptions({
+  name: "BaseEditor"
+});
+
+const mode = "default";
+// 编辑器实例,必须用 shallowRef
+const editorRef = shallowRef();
+
+// 内容 HTML
+const valueHtml = ref("<p>你好</p>");
+
+// 模拟 ajax 异步获取内容
+onMounted(() => {
+  setTimeout(() => {
+    valueHtml.value = "<p>我是模拟的异步数据</p>";
+  }, 1500);
+});
+
+const toolbarConfig: any = { excludeKeys: "fullScreen" };
+const editorConfig = { placeholder: "请输入内容..." };
+
+const handleCreated = editor => {
+  // 记录 editor 实例,重要!
+  editorRef.value = editor;
+};
+
+// 组件销毁时,也及时销毁编辑器
+onBeforeUnmount(() => {
+  const editor = editorRef.value;
+  if (editor == null) return;
+  editor.destroy();
+});
+</script>
+
+<template>
+  <div class="wangeditor">
+    <Toolbar
+      :editor="editorRef"
+      :defaultConfig="toolbarConfig"
+      :mode="mode"
+      style="border-bottom: 1px solid #ccc"
+    />
+    <Editor
+      v-model="valueHtml"
+      :defaultConfig="editorConfig"
+      :mode="mode"
+      style="height: 500px; overflow-y: hidden"
+      @onCreated="handleCreated"
+    />
+  </div>
+</template>

+ 9 - 0
src/views/editor/components/index.ts

@@ -0,0 +1,9 @@
+import base from "./base.vue";
+import multi from "./multi.vue";
+import picUpload from "./picUpload.vue";
+
+const Base = base;
+const Multi = multi;
+const PicUpload = picUpload;
+
+export { Base, Multi, PicUpload };

+ 76 - 0
src/views/editor/components/multi.vue

@@ -0,0 +1,76 @@
+<script setup lang="ts">
+import ReCol from "@/components/ReCol";
+import { onBeforeUnmount, ref, shallowRef } from "vue";
+import "@wangeditor/editor/dist/css/style.css";
+import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
+
+defineOptions({
+  name: "MultiEditor"
+});
+
+// 模拟后端返回多个编辑器的数据
+const endEditorList = [
+  {
+    value: "<p>测试一</p>"
+  },
+  {
+    value: "<p>测试二</p>"
+  },
+  {
+    value: "<p>测试三</p>"
+  },
+  {
+    value: "<p>测试四</p>"
+  }
+];
+
+// 多个编辑器的情况下,前端必须进行处理,满足 Toolbar 组件的 editor 属性 所需的 shallowRef 格式
+const editorList = ref([]);
+endEditorList.forEach(edit => {
+  editorList.value.push({
+    value: edit.value,
+    // 编辑器实例,必须用 shallowRef
+    editorRef: shallowRef()
+  });
+});
+
+const mode = "default";
+
+const toolbarConfig: any = { excludeKeys: "fullScreen" };
+const editorConfig = { placeholder: "请输入内容..." };
+
+const handleCreated = (editor, index) => {
+  // 记录 editor 实例,重要!
+  editorList.value[index].editorRef = editor;
+};
+
+// 组件销毁时,也及时销毁编辑器
+onBeforeUnmount(() => {
+  return editorList.value.map(edit => {
+    if (edit.editorRef == null) return;
+    edit.editorRef.destroy();
+  });
+});
+</script>
+
+<template>
+  <el-row :gutter="30" justify="space-around">
+    <re-col :value="11" v-for="(edit, index) in editorList" :key="index">
+      <div class="wangeditor">
+        <Toolbar
+          :editor="edit.editorRef"
+          :defaultConfig="toolbarConfig"
+          :mode="mode"
+          style="border-bottom: 1px solid #ccc"
+        />
+        <Editor
+          v-model="edit.value"
+          :defaultConfig="editorConfig"
+          :mode="mode"
+          style="height: 300px; overflow-y: hidden"
+          @onCreated="editor => handleCreated(editor, index)"
+        />
+      </div>
+    </re-col>
+  </el-row>
+</template>

+ 70 - 0
src/views/editor/components/picUpload.vue

@@ -0,0 +1,70 @@
+<script setup lang="ts">
+import { onBeforeUnmount, ref, shallowRef } from "vue";
+import "@wangeditor/editor/dist/css/style.css";
+import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
+
+defineOptions({
+  name: "picUpload"
+});
+
+const mode = "default";
+// 编辑器实例,必须用 shallowRef
+const editorRef = shallowRef();
+
+// 内容 HTML
+const valueHtml = ref(
+  "<p>仅提供代码参考,暂不可上传图片,可根据实际业务改写</p>"
+);
+const toolbarConfig: any = { excludeKeys: "fullScreen" };
+const editorConfig = { placeholder: "请输入内容...", MENU_CONF: {} };
+
+// 更多详细配置看 https://www.wangeditor.com/v5/menu-config.html#%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87
+editorConfig.MENU_CONF["uploadImage"] = {
+  // 服务端上传地址,根据实际业务改写
+  server: "",
+  // form-data 的 fieldName,根据实际业务改写
+  fieldName: "file",
+  // 选择文件时的类型限制,根据实际业务改写
+  allowedFileTypes: ["image/png", "image/jpg", "image/jpeg"],
+  // 自定义插入图片
+  customInsert(res: any, insertFn) {
+    // res.data.url是后端返回的图片地址,根据实际业务改写
+    if (res.data.url) {
+      setTimeout(() => {
+        // insertFn插入图片进编辑器
+        insertFn(res.data.url);
+      }, 2000);
+    }
+  }
+};
+
+const handleCreated = editor => {
+  // 记录 editor 实例,重要!
+  editorRef.value = editor;
+};
+
+// 组件销毁时,也及时销毁编辑器
+onBeforeUnmount(() => {
+  const editor = editorRef.value;
+  if (editor == null) return;
+  editor.destroy();
+});
+</script>
+
+<template>
+  <div class="wangeditor">
+    <Toolbar
+      :editor="editorRef"
+      :defaultConfig="toolbarConfig"
+      :mode="mode"
+      style="border-bottom: 1px solid #ccc"
+    />
+    <Editor
+      v-model="valueHtml"
+      :defaultConfig="editorConfig"
+      :mode="mode"
+      style="height: 500px; overflow-y: hidden"
+      @onCreated="handleCreated"
+    />
+  </div>
+</template>

+ 20 - 48
src/views/editor/index.vue

@@ -1,41 +1,12 @@
 <script setup lang="ts">
-import "@wangeditor/editor/dist/css/style.css"; // 引入 css
-import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
-import { useRenderIcon } from "@/components/ReIcon/src/hooks";
-import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue";
-import Edit from "@iconify-icons/ep/edit";
+import { ref } from "vue";
+import { Base, Multi, PicUpload } from "./components";
 
 defineOptions({
   name: "Editor"
 });
 
-const mode = "default";
-// 编辑器实例,必须用 shallowRef
-const editorRef = shallowRef();
-
-// 内容 HTML
-const valueHtml = ref("<p>hello</p>");
-
-// 模拟 ajax 异步获取内容
-onMounted(() => {
-  setTimeout(() => {
-    valueHtml.value = "<p>模拟 Ajax 异步设置内容</p>";
-  }, 1500);
-});
-
-const toolbarConfig: any = { excludeKeys: "fullScreen" };
-const editorConfig = { placeholder: "请输入内容..." };
-
-// 组件销毁时,也及时销毁编辑器
-onBeforeUnmount(() => {
-  const editor = editorRef.value;
-  if (editor == null) return;
-  editor.destroy();
-});
-
-const handleCreated = editor => {
-  editorRef.value = editor; // 记录 editor 实例,重要!
-};
+const activeNames = ref(["1"]);
 </script>
 
 <template>
@@ -47,7 +18,6 @@ const handleCreated = editor => {
           <el-link
             href="https://www.wangeditor.com"
             target="_blank"
-            :icon="useRenderIcon(Edit)"
             style="margin: 0 4px 5px; font-size: 16px"
           >
             Wangeditor
@@ -55,20 +25,22 @@ const handleCreated = editor => {
         </span>
       </div>
     </template>
-    <div class="wangeditor">
-      <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>
+    <el-collapse v-model="activeNames" accordion>
+      <el-collapse-item title="基础用法" name="1">
+        <Base />
+      </el-collapse-item>
+      <el-collapse-item title="多个富文本" name="2">
+        <Multi />
+      </el-collapse-item>
+      <el-collapse-item title="自定义图片上传" name="3">
+        <PicUpload />
+      </el-collapse-item>
+    </el-collapse>
   </el-card>
 </template>
+
+<style lang="scss" scoped>
+:deep(.el-collapse-item__header) {
+  padding-left: 10px;
+}
+</style>