mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	feat: wangeditor富文本添加多个富文本和自定义图片上传示例
				
					
				
			This commit is contained in:
		
							parent
							
								
									68ca7549c3
								
							
						
					
					
						commit
						82e994434a
					
				
							
								
								
									
										56
									
								
								src/views/editor/components/base.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/views/editor/components/base.vue
									
									
									
									
									
										Normal file
									
								
							@ -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
									
								
								src/views/editor/components/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/views/editor/components/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -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
									
								
								src/views/editor/components/multi.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/views/editor/components/multi.vue
									
									
									
									
									
										Normal file
									
								
							@ -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
									
								
								src/views/editor/components/picUpload.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/views/editor/components/picUpload.vue
									
									
									
									
									
										Normal file
									
								
							@ -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>
 | 
				
			||||||
@ -1,41 +1,12 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
 | 
					import { ref } from "vue";
 | 
				
			||||||
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
 | 
					import { Base, Multi, PicUpload } from "./components";
 | 
				
			||||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
					 | 
				
			||||||
import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue";
 | 
					 | 
				
			||||||
import Edit from "@iconify-icons/ep/edit";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({
 | 
					defineOptions({
 | 
				
			||||||
  name: "Editor"
 | 
					  name: "Editor"
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const mode = "default";
 | 
					const activeNames = ref(["1"]);
 | 
				
			||||||
// 编辑器实例,必须用 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 实例,重要!
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
@ -47,7 +18,6 @@ const handleCreated = editor => {
 | 
				
			|||||||
          <el-link
 | 
					          <el-link
 | 
				
			||||||
            href="https://www.wangeditor.com"
 | 
					            href="https://www.wangeditor.com"
 | 
				
			||||||
            target="_blank"
 | 
					            target="_blank"
 | 
				
			||||||
            :icon="useRenderIcon(Edit)"
 | 
					 | 
				
			||||||
            style="margin: 0 4px 5px; font-size: 16px"
 | 
					            style="margin: 0 4px 5px; font-size: 16px"
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            Wangeditor
 | 
					            Wangeditor
 | 
				
			||||||
@ -55,20 +25,22 @@ const handleCreated = editor => {
 | 
				
			|||||||
        </span>
 | 
					        </span>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </template>
 | 
					    </template>
 | 
				
			||||||
    <div class="wangeditor">
 | 
					    <el-collapse v-model="activeNames" accordion>
 | 
				
			||||||
      <Toolbar
 | 
					      <el-collapse-item title="基础用法" name="1">
 | 
				
			||||||
        style="border-bottom: 1px solid #ccc"
 | 
					        <Base />
 | 
				
			||||||
        :editor="editorRef"
 | 
					      </el-collapse-item>
 | 
				
			||||||
        :defaultConfig="toolbarConfig"
 | 
					      <el-collapse-item title="多个富文本" name="2">
 | 
				
			||||||
        :mode="mode"
 | 
					        <Multi />
 | 
				
			||||||
      />
 | 
					      </el-collapse-item>
 | 
				
			||||||
      <Editor
 | 
					      <el-collapse-item title="自定义图片上传" name="3">
 | 
				
			||||||
        style="height: 500px; overflow-y: hidden"
 | 
					        <PicUpload />
 | 
				
			||||||
        v-model="valueHtml"
 | 
					      </el-collapse-item>
 | 
				
			||||||
        :defaultConfig="editorConfig"
 | 
					    </el-collapse>
 | 
				
			||||||
        :mode="mode"
 | 
					 | 
				
			||||||
        @onCreated="handleCreated"
 | 
					 | 
				
			||||||
      />
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </el-card>
 | 
					  </el-card>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					:deep(.el-collapse-item__header) {
 | 
				
			||||||
 | 
					  padding-left: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user