在项目开发中,很多人应该都会用到「富文本编辑器」去实现文章、图片,甚至视频的撰写,WangEditor 在 PC 端还是挺好用的。
我并非是 WangEditor 的作者,只是一个使用者。
在这场 chat 中你能学到:
适合人群:对富文本编辑器有兴趣,又不知从何入手的工程师
注:本场 chat 的代码地址如下
后端代码地址 URL:https://gitee.com/hotstrip/uploadImageDemo
前端代码地址 URL:https://gitee.com/hotstrip/WangEditorDemo_front
这场 chat 的目录:
对于一个不熟悉的组件,如何最快的上手?一般来说,官网和文档是不二选择。官方网站如下:WangEditor
在上面的官网文档上,一共给出了 3 种安装方式:
无论使用哪种方式,原理是一样的,都是加载 js 文件到项目中。本场 chat 使用 Vue.js 做前端开发,因此使用 npm 方式引入是最方便的。
引入方式很简单,安装 Node 环境之后在命令行工具里面输入下面的命令就行:
npm install -S wangeditor /** * -S 参数表示安装到本地 * 对于 Vue 项目会在 package.json 文件里自动更新依赖, * 之后在别的电脑上运行电脑就无需再次手动安装, * 执行 npm install 命令就可以跟随其他 package.json 中的依赖一起安装了 * /
安装之后如何初始化呢?先不去考虑代码实现,从思维上来讲就 2 个步骤:
然后创建富文本编辑器就交给 WangEditor 的组件去实现,怎么实现的不用在意,它就像是一个黑盒子,我们给它需要的东西,它就会给我们想要的东西。
理解了思路,那么剩下的就简单了,核心部分代码如下:
/** * 用了 Vue 的组件,下面需要关注的就是 这一行 * 提供了一个 HTML 的 DOM 节点,对应上面的第一步 * /
对于第二步,让我们思考一个问题,编辑器很可能会有多个地方调用对吧,那么独立成组件会更加合适吧。对应的使用场景大概像这样——富文本编辑器在子组件里免渲染,其他页面按需引入该组件,同时页面能实时设置和获取到富文本编辑器里面的内容。那么独立组件会面临几个问题:
这两个问题,本质上就是父子组件的传递参数问题,父组件到子组件用 props 属性,子组件到父组件用 $emit 函数。核心代码如下:
props: { // 传递过来的编辑器内容参数,用于设置编辑器内容 content: { type: String, default: '' }},data() { return { // 真正的编辑器里的内容 editorContent: '', // 编辑器对象 editor: null }},watch: { // watch 表示监听 当父组件的内容变化时需要更新编辑器的内容 content() { this.editor.txt.html(this.content) }},/** * 这里使用了 Vue 的 mounted 函数钩子,这属于 Vue 生命周期的一个阶段 */mounted() { // 初始化 this.editor = new E(this.$refs.editorForm) // 当编辑器内容变化的时候通知父组件 this.editor.customConfig.onchange = (html) => { this.editorContent = html // 通知父级控件方法,富组件可以通过 editorContent 事件去获取最新的编辑器内容 this.$emit('editorContent', html) } this.editor.create() this.editor.txt.html(this.content)}
以上就是子组件的核心代码部分,针对父组件部分就简单了,引入子组件,添加子组件定义的 editorContent 事件就行了。核心代码如下:
WangEditor Demo
// 子组件将会在这里渲染出来 指定初始化的数据,以及监听数据更新的事件 效果区域展示:
完成了这一步,最基本的编辑器就已经好了,效果如下:
关于上传图片一般用 Base64 或者 form 表单上传,前者是把一张图片转换成 Base64 编码,然后用 img 标签的 src 属性中加上 data:image/jpeg;base64, 前缀交给浏览器渲染出来;后者是用 HTTP 方式上传到服务器上,然后通过 URI 访问图片资源。
使用 Base64 方式,图片不需要上传到服务器,当作字符串一样保存就行,但是字符串长度会很长很长;后者会占用服务器资源作存储,但返回给前端就是一串 URI 地址。
再回到 form 表单上传图片,既然是通过 HTTP 方式,那么肯定会涉及到后端。但不管怎么样都是从 HTTP 的请求体里面拿到图片,然后读取文件流,存储到服务器上,最后返回该图片可访问的 URI 资源。
对于 WangEditor 编辑器的上传图片,同样提供了 Base64 上传和接口上传图片两种方式,下面就是后端上传图片接口的实现。
上面已经提到过,后台提供上传图片接口,这个接口的主要作用就是从 HTTP 请求中获取文件流信息,然后保存到服务器上,同时返回文件的访问地址 URI。重点就是要处理好图片的存储和返回图片存储地址,废话不多说,直接上代码:
/** * Created by Administrator on 2019/9/6. * 上传图片 Controller 类 */@RestControllerpublic class UploadImageController { private static Logger logger = LoggerFactory.getLogger(UploadImageController.class); /** * 上传图片接口地址 * @param multipartHttpServletRequest * @return */ @PostMapping(value = "/uploadImage") public Object uploadImage(MultipartHttpServletRequest multipartHttpServletRequest){ // 图片存储路径 String path = "src/main/resources/static"; // 返回值 HashMap map = new HashMap(); List data = new ArrayList<>(); // 取得request中的所有文件名 Iterator iterator = multipartHttpServletRequest.getFileNames(); // 遍历 while (iterator.hasNext()) { // 取得上传文件 MultipartFile multipartFile = multipartHttpServletRequest.getFile(iterator.next()); if (multipartFile != null) { // 文件名 String fileName = multipartFile.getOriginalFilename(); // 获取文件拓展名 String extName = FileUtil.getExtName(fileName); if (StringUtils.isEmpty(extName)) { logger.error("文件后缀名称为空,文件可能有问题..."); map.put("errno", 1); map.put("data", data); return map; } // 保证 文件夹存 File fileDir = new File(path); if (!fileDir.exists()){ fileDir.mkdirs(); } File file = new File(fileDir, fileName); // 拷贝文件流 到上面的文件 FileUtil.copyInputStreamToFile(multipartFile, file); // 构建图片的可访问地址 String webUrl = multipartHttpServletRequest.getScheme() + "://" + multipartHttpServletRequest.getServerName() + ":" + multipartHttpServletRequest.getServerPort() + multipartHttpServletRequest.getContextPath(); String imageUrl = file.getPath().substring(path.length()).replaceAll("\\\\", "/"); logger.info("文件路径: {}", webUrl + imageUrl); // 添加到数组中 data.add(webUrl + imageUrl); } } // 返回前端需要的格式 map.put("errno", 0); map.put("data", data); return map; }}
上面的代码就提供了一个上传图片的接口地址,图片会存储在项目的 classpath 下面的 static 目录中,返回值的格式需要和 WangEditor 要求的格式保持一致。
与此同时,前端的富文本编辑器组件中也需要配置上传图片接口地址,如下:红框中的地址就是后台项目的服务上传图片接口访问地址,前半部分可以在 classpath 中的 application.yml 文件修改,指定端口、项目访问地址,以及静态资源存储地址:
到了这里呢,本场 chat 就算是已经结束了,最后再梳理下整体的逻辑。
一开始遇到新的需求,需要用到不熟悉的组件,最好的开始就是官方文档,从官方文档其实可以看到很多东西。比如如何开始的步骤、提供的功能、设计思路等,然后需要结合自己的需求去做取舍和调整,对于一些苛刻的要求能否用提供的功能去间接实现等。
然后提供了基于 Vue 框架的 WangEditor 富文本编辑器前端部分的设计思路和代码实现,之后简单说明了两种上传图片的方式的优劣。
最后使用 Java 和 Spring Boot 完成了后端部分的图片上传接口,之后修改前端的配置就搞定了一个简单的案例。
注:本场 chat 的代码地址如下
后端代码地址 URL:https://gitee.com/hotstrip/uploadImageDemo
前端代码地址 URL:https://gitee.com/hotstrip/WangEditorDemo_front
本文首发于 GitChat,未经授权不得转载,转载需与 GitChat 联系。
阅读全文: http://gitbook.cn/gitchat/activity/5d71c2eaf755eb3ccec5819b
您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。