「Vue3实践」- vue3中实现WPS文档操作、富文本实现文本编辑
富文本编辑器,在ToB项目中早已屡见不鲜,通常可以在form表单中看见它的身影;近年来文档协作办公场景,在项目中也逐渐增多。最近的项目中,刚好使用到了这两种场景,今天整理了一下思路,来讲解下如何在vue3中实现这两种需求。
一、项目需求
-
背景:最近接触到的项目,有两个重点需求需要考虑;第一个是涉及到对文档的操作,多人能够协作编辑、同时需要满足审阅、留痕、清稿操作。第二个是在form表单中,编辑通知正文,将正文信息传递到后端接口,用于保存或者下发信息。
针对第一个,第一反应就是办公软件的协作处理,由于公司有文档中心中台,业务项目对接就可使用,但中台对接方面提供的是服务端的能力,前端这块,针对业务需求需要自己处理。于是查阅官网资料,自己进行了少量封装,最终实现了在vue3中的效果。而第二个需求,最初也是考虑使用WPS提供的能力来实现,但WPS带有页眉页脚、头部导航、页面边框等的展示,这些在form表单中显然不合适,虽然WPS也提供定制页面的开发,但这块也相对花费时间,而且从使用场景上来说,WPS侧重于办公协作方面,在form表单中似乎也有点“大材小用”,于是就选择了富文本编辑器。
-
技术
- 文档操作:基于
WPS
开发,使用的是Web Office SDK for Javascript
插件,后续简称JS-SDK
。- 富文本编辑:
WangEditor5
二、vue3中的WPS文档操作
WPS开放平台
提供了接入指导,在接入过程中,涉及到服务端
与前端
两方面的内容,在服务端方面,与中台对接提供接口能力,在前端方面,需要使用到JS-SDK
插件接入开发,官网上目前提供的是纯js的开发,要使用到VUE项目中,则需要自己进行部分封装。
2.1 实现步骤
-
下载并处理
ES6
模块化规范文件
官网下载JS-SDK
插件,下载的是一个压缩包,压缩包中提供了AMD
,CommonJs
、ES6
多种模块化规范的包,当前项目时基于vite
开发的,因此引入ES6
模块化规范的web-office-sdk-v1.1.8.es.js
文件,存放在src/static
目录下,可以根据自己需要,更改文件路径/名称。
由于目前的vite
项目,使用的是ts
开发,因此引入的js
文件并不能直接使用,需要首先建立ts声明文件
。在src/static
文件夹下,新建index.d.ts
文件。有了声明文件后,在ts文件中即可引入了。
index.d.ts
declare module "*.js" {
const WebOfficeSDK: any
export = WebOfficeSDK
}
-
全局注册
在main.ts中使用provide
全局注册,以便在其他组件中使用。app.provide("WPS", WebOfficeSDK)
-
封装
WPS
组件
组件中,对WPS
进行配置,使用插件的config
函数,配置WPS
的显示模式,文件预览地址、挂载节点,同时进行授权。其中文件预览地址
,授权token
均需要父组件从接口中获得提供。
// WpsViewer.vue组件
<template>
<div id="wps-viewer"></div>
</template>
<script lang="ts" setup>
import { onMounted, inject } from "vue"
const props = defineProps<{
wps_url: string
simpleMode: boolean
mountNode: string
token: string
}>()
const WPS: any = inject("WPS")
// 根据后端返回的wps_url打开wps文档编辑器
function openWpsViewer() {
const WpsApp = WPS.config({
mode: props.simpleMode ? "simple" : "normal", // 显示模式,simple不显示工具栏与头部导航
url: props.wps_url, // 文件预览地址
mount: document.querySelector(`${props.mountNode}`), // 挂载节点
})
WpsApp.setToken({ token: props.token }) // 授权
WpsApp.tokenData = props.token
WpsApp.iframe.height = "500px"
}
onMounted(() => {
openWpsViewer()
})
</script>
<style lang="scss" scoped></style>
-
父组件调用WPS
在父组件中调用WPS
组件,其中父组件可以当做一个单独的.vue
文件处理,或者嵌入在其他页面中。由于办公协作,一般是新打开的浏览器窗口,因此我们将父组件放在单独的文件中,通过router
来控制它的展现形式。其中wpsUrl
和token
从接口中获取。
// 父组件WpsEditor.vue
<template>
<wps-viewer
mountNode="#app"
:wps_url="wpsUrl"
:simpleMode="false"
:token="token">
</wps-viewer>
</template>
-
路由控制
通常我们的协作文件,需要在一个页面中触发某个操作,如点击打开文件按钮、点击预览、点击编辑等操作按钮,这时候可由路由来控制页面,由于办公协作通常是新打开的浏览器窗口,因此这里需要使用到router.resolve()
方法。
// 触发
function handleClick(fileId: any) {
const { href } = router.resolve({ path: "/wpsEditor", query: { fileId } })
window.open(href, "_blank")
}
2.2 实现效果
三、vue3中富文本编辑
从上面截图中,可以看到在项目中,有个form表单需要填写通知书正文的需求,正文里面可以选择已经有的格式模板,在正文编写之后,需要提交到接口中进行保存。在这里我选择了使用wangEditor 5
来实现。
3.1 实现步骤
-
插件安装
yarn add @wangeditor/editor, @wangeditor/editor-for-vue
两个插件
-
页面引入
在页面中需要提供工具栏与编辑器区域,提供工具栏、编辑器相关配置,包括对工具栏菜单个性化配置;其次,需要在页面挂载时,设置模板内容,如果模板内容从其他接口中获取,可以设置获取格式;最后,需要引入插件样式。
<el-form-item label="通知书正文" prop="noticeContext">
<div class="editor-wrapper">
<!-- 工具栏 -->
<Toolbar
id="toolbar-wrapper"
:editor="editorRef"
:defaultConfig="toolbarConfig"
style="min-height:100px;1px solid #ccc"
/>
<!-- 编辑器 -->
<Editor
id="editor-wrapper"
v-model="valueHtml"
:defaultConfig="editorConfig"
style="height: 370px; overflow-y: hidden"
@onCreated="handleCreated"
/>
</div>
</el-form-item>
// 编辑器实例
const editorRef = shallowRef()
const valueHtml = ref("<p>预加载</p>")
const editorConfig = {
placeholder: "内容区域...",
MENU_CONF: { // 菜单配置 },
}
const toolbarConfig = {} // 工具栏配置
const handleCreated = (editor: any) => {
editorRef.value = editor // 记录 editor 实例
}
// 自定义初始化模板内容
const templateValue = `
<p style='text-align: left;'>〔2022〕某某单位审字第***号</p>
<p>审计通知书</p>
<p>正文正文正文</p>`
onMounted(() => {
setTimeout(() => {
valueHtml.value = templateValue
}, 1500)
})
// 引入样式文件
<style src="@wangeditor/editor/dist/css/style.css"></style>
3.2 实现效果
这里由于项目保密性,只截取部分图,设置的模板内容在页面加载过程中就可以展示,然后编辑器功能和使用可以自己查阅官网。
以往的很多项目都是针对纯js进行实现的,本文提供vue3的方式来具体实现,大家可以进行参阅。目前针对Vue3系列的项目文章,总计写完了3篇,其它两篇可查阅下面链接,项目中遇到的实战案例,后续会持续更新。
转载自:https://juejin.cn/post/7097057321888514078