vue3 wangeditor 富文本使用自定义上传图片

wangeditor

wangeditor

下载

pnpm add @wangeditor/editor

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

mode: ‘default’ 默认模式 - 集成了 wangEditor 所有功能
mode: ‘simple’ 简洁模式 - 仅有部分常见功能,但更加简洁易用

基础结构

<script lang="ts" setup>
import "@wangeditor/editor/dist/css/style.css"; // 引入 css

import { onBeforeUnmount, ref, shallowRef } from "vue";

import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { IToolbarConfig, IEditorConfig, IDomEditor } from "@wangeditor/editor";

// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();

// 模式
const mode = ref("default");

/* 工具栏配置 */
const toolbarConfig: Partial<IToolbarConfig> = {};

// 编辑器配置
const editorConfig: Partial<IEditorConfig> = { placeholder: "请输入内容..." };

// 内容 HTML
const valueHtml = ref("");

function handleCreated(editor: IDomEditor) {
	// 记录 editor 实例,重要!
	editorRef.value = editor;
}

// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
	const editor = editorRef.value;
	if (editor == null) return;
	editor.destroy();
});
</script>

<template>
	<div style="border: 1px solid #ccc">
		<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>
</template>

工具栏配置

/* 工具栏配置 */
const toolbarConfig: Partial<IToolbarConfig> = {
	// 排除的菜单选项
	excludeKeys: [
		"insertTable",
		"insertImage", // 排除菜单组 写菜单组 key 的值即可,如排除图片中的 网络图片选项 key("insertImage")
	],
};

获取菜单选项列表 toolbar
setTimeout 以便获取值 toolbar

import { IToolbarConfig, IEditorConfig, IDomEditor, DomEditor } from "@wangeditor/editor";

function handleCreated(editor: IDomEditor) {
	setTimeout(() => {
		const toolbar = DomEditor.getToolbar(editor);
		const toolbarKeys = toolbar?.getConfig().toolbarKeys;
		console.log("toolbarKeys", toolbarKeys);
	}, 0);
}

编辑器配置

编辑器配置中 onXxx 格式的生命周期函数,必须通过 Vue 事件来传递,不可以放在 editorConfig 中

编辑器内容、选区变化时的回调函数。

<template>
    <Editor
        @onChange="handleChange"
    />
</template>
<script lang="ts" setup>
    function handleChange(editor: IDomEditor) {
        console.log("content", editor.children);
    }
</script>

菜单配置

菜单配置是工具栏的菜单项的详细配置,该配置也在编辑器配置下

获取菜单所有 key

function handleCreated(editor: IDomEditor) {
	editor.getAllMenuKeys();
}

获取某菜单默认配置 --> 获取图片默认配置

function handleCreated(editor: IDomEditor) {
	const uploadImage = editor.getMenuConfig("uploadImage");
	console.log("uploadImage", uploadImage);
}

修改配置 --> 修改颜色

// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
	placeholder: "请输入内容...",
	autoFocus: false,

	// 修改配置
	MENU_CONF: {
		// 颜色
		color: {
			colors: ["#000", "#333", "#666"],
		},
	},
};

// 单独拿出来配置,结果与上面一样
editorConfig.MENU_CONF["color"] = {
	colors: ["#000", "#333", "#666"],
};

上传图片

基本上传

const editorConfig: Partial<IEditorConfig> = {
	MENU_CONF: {
		// 上传图片的配置
		uploadImage: {
			// 必填 请求地址
			server: "/api/file",

			// file 文件的字段名
			fieldName: "file",

			// 其他传递的参数, 加在 formData 中
			meta: {
				scene: "avatar",
			},

			// 请求头:存放 token
			headers: {
				Authorization: " ",
			},

			// 单个文件的最大体积限制,默认为 2M
			maxFileSize: 1 * 1024 * 1024, // 1M

			// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
			allowedFileTypes: ["image/*"],

			// 上传前的回调
			onBeforeUpload(file: File) {
				console.log("上传前的回调", file);
				// return file;
			},
			// 上传成功
			onSuccess(file: File, res: any) {
				console.log(` 上传成功`, res);
			},
			// 单个文件上传失败
			onFailed(file: File, res: any) {
				console.log(` 上传失败`, res);
			},

			// 上传错误,或者触发 timeout 超时
			onError(file: File, err: any, res: any) {
				console.log(`传出错`, err);
				console.log(`上传出错`, res);
			},
		},
	},
};

服务端 response body 无法按照上述格式,可以使用下文的 customInsert

/**
 *  从 res 中找到 url alt href ,然后插入图片
 * "url": "xxx", // 图片 src ,必须
 * "alt": "yyy", // 图片描述文字,非必须
 * "href": "zzz" // 图片的链接,非必须
 */

type InsertFnType = (url: string, alt: string, href: string) => void;
const editorConfig: Partial<IEditorConfig> = {
	MENU_CONF: {
		// 自定义插入图片
		customInsert(res: any, insertFn: InsertFnType) {
			// res 即服务端的返回结果
			console.log("自定义插入图片", res);

			insertFn(res.data.url, "", "");
		},
	},
};

自定义上传图片逻辑

type InsertFnType = (url: string, alt: string, href: string) => void;
const editorConfig: Partial<IEditorConfig> = {
	MENU_CONF: {
		// 自定义上传
		async customUpload(file: File, insertFn: InsertFnType) {
			// file 即选中的文件
			console.log("自定义上传", file);

			// 自己实现上传,并得到图片 url alt href
			const formData = new FormData();
			formData.append("file", file, file?.name);
			formData.append("scene", "avatar");
			// 上传接口
			const res = await upload(formData);

			// 最后插入图片
			insertFn(res.data.url, "", "");
		},
	},
};

function checkImageSize(fileTypeList: string[] = ["image/jpeg", "image/jpg", "image/png"]) {
	const flag = fileTypeList.some((item) => file.type === item);
	if (!flag) return false;
	return true;
}
function checkImageType(size: number = 1024 * 1024 * 1) {
	if (file.size > size) return false;
	return true;
}
  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您介绍一下使用Vue3封装WangEditor富文本组件的步骤。 首先,我们需要安装WangEditorVue3,可以通过以下命令进行安装: ```bash npm install wangeditor@latest npm install vue@next ``` 接着,我们可以在Vue3的组件中使用WangEditor。下面是一个简单的示例: ```vue <template> <div ref="editorElem"></div> </template> <script> import WangEditor from 'wangeditor' export default { mounted() { const editor = new WangEditor(this.$refs.editorElem) editor.create() } } </script> ``` 在上面的代码中,我们通过import导入了WangEditor,并在mounted钩子函数中创建了一个新的编辑器实例。注意,我们需要在组件的模板中添加一个ref属性,用于引用编辑器的DOM元素。 如果您需要进一步封装WangEditor组件,可以考虑将其封装为一个Vue组件,以便在其他地方重复使用。下面是一个简单的示例: ```vue <template> <div :id="editorId"></div> </template> <script> import WangEditor from 'wangeditor' export default { props: { value: String, placeholder: String, height: { type: String, default: '300px' } }, data() { return { editorId: `editor-${Math.random().toString(36).substr(2, 9)}`, editor: null } }, mounted() { this.editor = new WangEditor(`#${this.editorId}`) this.editor.config.height = this.height this.editor.config.placeholder = this.placeholder this.editor.config.onchange = this.handleChange this.editor.create() this.editor.txt.html(this.value) }, methods: { handleChange() { this.$emit('input', this.editor.txt.html()) } }, beforeUnmount() { this.editor.destroy() } } </script> ``` 在上面的代码中,我们定义了一个WangEditor组件,并通过props接收了一些参数,包括组件的初始值、占位符和高度等。在mounted钩子函数中,我们创建了一个新的编辑器实例,并通过config属性设置了一些编辑器的配置项,包括高度、占位符和内容变化时的回调函数等。我们还通过handleChange方法监听了编辑器内容的变化,并通过$emit方法向父组件发送了一个input事件,以便在父组件中更新组件的绑定值。最后,我们在beforeUnmount钩子函数中销毁了编辑器实例,以避免内存泄漏。 使用时,您可以像使用其他自定义组件一样,在Vue3的模板中引用WangEditor组件,并通过v-model指令绑定组件的值: ```vue <template> <div> <wangeditor v-model="content" placeholder="请输入内容" height="500px" /> <div>{{ content }}</div> </div> </template> <script> import WangEditor from '@/components/WangEditor.vue' export default { components: { WangEditor }, data() { return { content: '' } } } </script> ``` 在上面的代码中,我们通过import导入了WangEditor组件,并在模板中引用了该组件。我们还通过v-model指令绑定了组件的值,以便在父组件中获取和更新该值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值