一、介绍

通过 Vue2、Ant Design Vue、wangEditor 和 less 的组合,成功实现了一个功能完整的 Word 文档转 HTML 工具。用户可以复制 Word 文档,将其转换为 HTML,并使用富文本编辑器对转换后的内容进行编辑。

二、技术选型与环境搭建

技术选型

  1. Vue2:作为基础框架,提供响应式数据绑定和组件化开发模式。
  2. Ant Design Vue:提供美观、易用的 UI 组件,加快开发速度。
  3. wangEditor:专业的富文本编辑器,支持多种格式转换。
  4. less:CSS 预处理语言,提供变量、嵌套、混合等功能,增强 CSS 的可维护性。

安装所需依赖

# 安装Ant Design Vue
npm install ant-design-vue --save
# 安装wangEditor
npm install @wangeditor/editor-for-vue --save
# 安装less和less-loader
npm install less less-loader --save-dev

 在main.js中引入ant-design-vue

import Vue from 'vue'
import App from './App.vue'
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'

Vue.use(Antd)

new Vue({
  render: h => h(App),
}).$mount('#app')

 三、核心功能实现

<template>
	<div class="wangEditor">
		<div class="container">
			<Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig"
				:mode="mode" />
			<Editor style="height: 300px; overflow-y: hidden;" v-model="text" :defaultConfig="editorConfig" :mode="mode"
				@onCreated="onCreated" />
		</div>
		<div class="submit_btn">
			<a-button type="primary" @click="getEditorContext">获取内容</a-button>
		</div>
		<div class="preview_box">
			<div class="header-box">
				<div class="title">html</div>
				<a class="copy_btn" @click="copyClick"><a-icon type="copy" />Copy code</a>
			</div>
			<div class="content-box" v-text="html"></div>
		</div>
	</div>
</template>

<script>
import Vue from 'vue'
import {
	Editor,
	Toolbar
} from '@wangeditor/editor-for-vue'

export default Vue.extend({
	components: {
		Editor,
		Toolbar
	},
	data() {
		return {
			editor: null,
			text: '',
			html: '',
			toolbarConfig: {},
			editorConfig: {
				placeholder: '请输入内容...',
				MENU_CONF: {
					uploadImage: {
						server: '/api/upload',
						// form-data fieldName ,默认值 'wangeditor-uploaded-image'
						fieldName: 'your-custom-name',

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

						// 最多可上传几个文件,默认为 100
						maxNumberOfFiles: 1,

						// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
						allowedFileTypes: ['image/*'],
						// 跨域是否传递 cookie ,默认为 false
						withCredentials: false,

						// 超时时间,默认为 10 秒
						timeout: 30 * 1000, // 30 秒
						// 上传之前触发
						onBeforeUpload(file) {
							return file
						},

						// 上传进度的回调函数
						onProgress(progress) {
							// progress 是 0-100 的数字
							console.log('progress', progress)
						},

						// 单个文件上传成功之后
						onSuccess(file, res) {
							console.log(`${file.name} 上传成功`, res)
						},

						// 单个文件上传失败
						onFailed(file, res) {
							console.log(`${file.name} 上传失败`, res)
						},

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

					}
				}
			},
			mode: 'default', // or 'simple'
		}
	},
	methods: {
		onCreated(editor) {
			this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
		},
		getEditorContext() {
			this.html = this.editor.getHtml()
			console.log(this.editor.getHtml())
			console.log(this.editor.getText())
		},
		// 一键复制
		copyClick() {
			const that = this;
			let data = that.html;
			// navigator clipboard 需要https等安全上下文
			if (navigator.clipboard && window.isSecureContext) {
				// navigator clipboard 向剪贴板写文本
				navigator.clipboard.writeText(data).then(() => {
					that.$message.success("复制成功");
				}).catch(() => {
					that.$message.warning("复制失败");
				})
			}else{
				// 创建text area
				let textArea = document.createElement("textarea");
				textArea.value = data;
				// 使text area不在viewport,同时设置不可见
				textArea.style.position = "absolute";
				textArea.style.opacity = 0;
				textArea.style.left = "-999999px";
				textArea.style.top = "-999999px";
				document.body.appendChild(textArea);
				textArea.focus();
				textArea.select();
				return new Promise((res, rej) => {
					// 执行复制命令并移除文本框
					document.execCommand('copy') ? that.$message.success("复制成功") : that.$message.warning("复制失败")
					textArea.remove();
				});
			}
		}
	},
	mounted() {
		// 模拟 ajax 请求,异步渲染编辑器
		// this.$nextTick(()=>{
		// 	this.html = '<p>模拟 Ajax 异步设置内容 HTML</p>'
		// })
	},
	beforeDestroy() {
		const editor = this.editor
		if (editor == null) return
		editor.destroy() // 组件销毁时,及时销毁编辑器
	}
})
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style lang="less" scoped>
.wangEditor {
	width: 100%;
	height: 100%;
	padding: 0 30px;

	.container {
		border: 1px solid #cccccc;
	}

	.submit_btn {
		margin-top: 10px;
		display: flex;
		justify-content: flex-end;
	}

	.preview_box {
		width: 100%;
		height: 200px;
		word-break: break-all;
		background-color: #ffffff;
		margin-top: 15px;
		border: 1px solid #ff5500;
		overflow: auto;

		.header-box {
			height: 50px;
			border-bottom: 1px solid #ff5500;
			display: flex;
			justify-content: space-between;
			align-items: center;
			padding: 0 10px;
			user-select: none;
			.copy_btn {
				cursor: pointer;
			}
		}

		.content-box {
			padding: 10px;
		}
	}
}
</style>

 Ant Design Vue参考文档:Ant Design Vue

 wangEditor参考文档:wangEditor

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐