WangEditor 使用案例

在项目开发中,很多人应该都会用到「富文本编辑器」去实现文章、图片,甚至视频的撰写,WangEditor 在 PC 端还是挺好用的。

我并非是 WangEditor 的作者,只是一个使用者。

在这场 chat 中你能学到:

  1. WangEditor 基本的使用
  2. 如何完成一个简单完整的案例,用来撰写文章,上传图片
  3. 一些可能会遇到的问题剖析

适合人群:对富文本编辑器有兴趣,又不知从何入手的工程师

注:本场 chat 的代码地址如下

后端代码地址 URL:https://gitee.com/hotstrip/uploadImageDemo

前端代码地址 URL:https://gitee.com/hotstrip/WangEditorDemo_front

这场 chat 的目录:

  • WangEditor 如何引入到项目中——前端
  • 上传图片实现原理
  • 图片上传接口实现——后端
  • 总结

WangEditor 如何引入到项目中——前端

对于一个不熟悉的组件,如何最快的上手?一般来说,官网和文档是不二选择。官方网站如下:WangEditor

在上面的官网文档上,一共给出了 3 种安装方式:

  • 下载源文件 js 引入
  • 使用包管理工具引入(诸如 npm 之类)
  • 使用在线的 js (CDN)

无论使用哪种方式,原理是一样的,都是加载 js 文件到项目中。本场 chat 使用 Vue.js 做前端开发,因此使用 npm 方式引入是最方便的。

引入方式很简单,安装 Node 环境之后在命令行工具里面输入下面的命令就行:

npm install -S wangeditor /**  * -S 参数表示安装到本地 * 对于 Vue 项目会在 package.json 文件里自动更新依赖, * 之后在别的电脑上运行电脑就无需再次手动安装, * 执行 npm install 命令就可以跟随其他 package.json 中的依赖一起安装了 * /

安装之后如何初始化呢?先不去考虑代码实现,从思维上来讲就 2 个步骤:

  • 对于 HTML 需要提供一个 DOM 节点
  • 调用 WangEditor 组件的方法,跟上面的 DOM 节点关联

然后创建富文本编辑器就交给 WangEditor 的组件去实现,怎么实现的不用在意,它就像是一个黑盒子,我们给它需要的东西,它就会给我们想要的东西。

理解了思路,那么剩下的就简单了,核心部分代码如下:

/** * 用了 Vue 的组件,下面需要关注的就是 
这一行 * 提供了一个 HTML 的 DOM 节点,对应上面的第一步 * /

对于第二步,让我们思考一个问题,编辑器很可能会有多个地方调用对吧,那么独立成组件会更加合适吧。对应的使用场景大概像这样——富文本编辑器在子组件里免渲染,其他页面按需引入该组件,同时页面能实时设置和获取到富文本编辑器里面的内容。那么独立组件会面临几个问题:

  1. 页面传递内容参数给富文本编辑器组件
  2. 编辑器内容更新之后,引入富文本编辑器组件的页面能实时获取数据

这两个问题,本质上就是父子组件的传递参数问题,父组件到子组件用 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 使用案例_第1张图片

上传图片实现原理

关于上传图片一般用 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 要求的格式保持一致。

与此同时,前端的富文本编辑器组件中也需要配置上传图片接口地址,如下:WangEditor 使用案例_第2张图片红框中的地址就是后台项目的服务上传图片接口访问地址,前半部分可以在 classpath 中的 application.yml 文件修改,指定端口、项目访问地址,以及静态资源存储地址:

WangEditor 使用案例_第3张图片

总结

到了这里呢,本场 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 专享技术内容哦。

FtooAtPSkEJwnW-9xkCLqSTRpBKX

你可能感兴趣的:(WangEditor 使用案例)