Vue+ueditor坑中摸索

2,786 阅读6分钟

vue+UEditor

昨天的项目需求上出现了使用富文本的要求,本着百度大法好,就去百度上查看vue上有什么好用的富文本编辑器,恰好公司其它项目上用的到了ueditor富文本编辑器,本着造好的轮子拿来用原则。

首先

你得去ueditor官网下载最新编译的UEditor

这里我选的是1.4.3.3jsp版本的

将下载好的压缩包解压并命名UEditor放入到你的公共文件目录下

如果是vue-cli2创建的项目就把UEditor放入到公共文件夹static目录下

我这里是vue-cli3创建的项目,就把UEditor放入到public这个公共文件目录下

一、开始创建ueditor吧!

  1. 始在项目上创建一个uedtior子组件!

    <template>
      <div>
        <script id="editor" type="text/plain" ></script>
      </div>
    </template>
    
    <script>
      import '../../../public/UEditor/ueditor.config'
      import '../../../public/UEditor/ueditor.all'
      import '../../../public/UEditor/ueditor.parse'
      import '../../../public/UEditor/lang/zh-cn/zh-cn'
      export default {
        name: "UEditor",
        props: {
          id: {
              type: String
          },
          config: {
              type: Object
          }
        },
        data() {
          return {
            editor: null
          }
        },
        mounted() {
           //初始化UE
          let _this = this;
          _this.editor=window.UE.getEditor('editor',_this.config);
            //设置编辑器的内容
          _this.editor.addListener("ready", function () {
            //将 editor 传到父组件
            _this.$emit('getEditor',_this.editor)
            // _this.editor.setContent('<p>454646</p>'); // 确保UE加载完成后,放入内容。
          });
        },
        destoryed() {
          this.editor.destory();
        },
        methods:{
          getUEContent: function(){
              //获取内容方法 返回给父组件
           return this.editor.getContent();
          },
          getContentTxt: function(){
            return this.editor.getContentTxt();
          }
        }
      }
    </script>
    
  2. 父组件中的使用方式,接收父组件传递过来的参数,对编辑器进行初始化赋值。如果是修改文章就需要用到加载默认内容。

  3. 初始化编辑器,如果需要加载默认内容要在ready后处理

二、在父组件中使用uedtior组件

<template> 
        <div>
        	<u-editor :config=config ref="ueditor"></u-editor>
        </div>
    
    </template>
    <script>
        import UEditor from './ueditor'   
        export default{
    		//import引入的组件需要注入到对象中才能使用
    		components: {UEditor},
            data() {
    //这里存放数据
    return {
        config:{
            // 编辑器不自动被内容撑高
            autoHeightEnabled: false,
            // 初始容器高度
            initialFrameHeight: 240,
            // 初始容器宽度
            initialFrameWidth: null,
            autoFloatEnabled: true,
                    initialContent:'请输入内容',   //初始化编辑器的内			容,也可以通过textarea/script给值,看官网例子
                        autoClearinitialContent:true, //是否自动清除编辑器初始内容,注意:如果focus属性设置为true,这个也为真,那么编辑器一上来就会触发导致初始化的内容看不到了
                    BaseUrl: '',
                    UEDITOR_HOME_URL: '/UEditor/',
                },
                editor:{}
            };
            },
        }
    </script

至此就可以在页面中看到一个初始化之后的UEditor富文本编辑器了

这篇叫踩坑的文章当然没有这么简单的结束

在我写到这里的时候原以为是结束,万万没想到是开始。

  1. 上传功能出现错误是因为还没有交给后台去配置可以先放着
  2. ,如果想测试的可以用
        // 上传文件接口(这个地址是我为了方便各位体验文件上传功能搭建的临时接口,请勿在生产环境使用!!!)
        serverUrl: 'http://35.201.165.105:8000/controller.php',
    
    放在config里面
  3. 因为忽略了第二个错误,直接去百度查找第三个错误ZeroClipboard is not defined,这个真的是让人头大的一个错误,借鉴网上大佬的文章 打开public目录下的UEditor文件,找到third-party文件下面的ZeroClipboard文件,打开ZeroClipboard.js滑倒最下面会看到
        if (typeof define === "function" && define.amd) {
           define(function() {
             return ZeroClipboard;
           });
         } else if (typeof module === "object" && module && typeof module.exports === "object" && module.exports) {
           module.exports = ZeroClipboard;
         } else {
           window.ZeroClipboard = ZeroClipboard;
         }
    
    意思就是说
    • 如果当前页面的模块加载模式是AMD的 则定义模块
    • 如果是CommonJs的,则输出到模块 ZeroClipboard
    • 否则 把ZeroClipboard 定义为全局变量 解决它网上有两种方法,但是我这里就用简单暴力的方法 直接注释掉上面的判断,不使用模块加载模式来使用这个功能
        // if (typeof define === "function" && define.amd) {
          //  define(function() {
            //  return ZeroClipboard;
            //});
         // } else if (typeof module === "object" && module && //typeof module.exports === "object" && module.exports) {
          //  module.exports = ZeroClipboard;
         // } else {
            window.ZeroClipboard = ZeroClipboard;
          //}
    

但是,事情并没有这么简单的结束了

该报的错还是报,报的还是一样的错误,纠结是不是哪里路径错了,又重新梳理了下创建步骤,以及对照官网上的例子,发现并没有什么不同

经查看源码后,发现ueditor.all.js里面有ZeroClipboard字段,但是看了源码后发现并不是我想象的路径(看的有点头大),转头去看了ueditor.config.js,发现

  /**
      * 编辑器资源文件根路径。它所表示的含义是:以编辑器实例化页面为当前路径,指向编辑器资源文件(即dialog等文件夹)的路径。
      * 鉴于很多同学在使用编辑器的时候出现的种种路径问题,此处强烈建议大家使用"相对于网站根目录的相对路径"进行配置。
      * "相对于网站根目录的相对路径"也就是以斜杠开头的形如"/myProject/ueditor/"这样的路径。
      * 如果站点中有多个不在同一层级的页面需要实例化编辑器,且引用了同一UEditor的时候,此处的URL可能不适用于每个页面的编辑器。
      * 因此,UEditor提供了针对不同页面的编辑器可单独配置的根路径,具体来说,在需要实例化编辑器的页面最顶部写上如下代码即可。当然,需要令此处的URL等于对应的配置。
      * window.UEDITOR_HOME_URL = "/xxxx/xxxx/";
      */
     var URL = window.UEDITOR_HOME_URL || getUEBasePath();

到这里就发现因为忽略了上面报的第二个错误(疯狂锤自己)浪费了好多时间

这是 UEDITOR_HOME_URL 参数配置错误导致的。在 vue cli 2.x 生成的项目中使用本组件,默认值是 '/static/UEditor/',在 vue cli 3.x 生成的项目中,默认值是 process.env.BASE_URL + 'UEditor/' 。但这并不能满足所有情况。例如你的项目不是部署在网站根目录下,如"www.example.com/my-app/",你可…"。是否使用了相对路径、路由是否使用 history 模式、服务器配置是否正确等等都有可能会产生影响。总而言之:无论本地开发和部署到服务器,你所指定的 UEditor 资源文件是需要真实存在的,vue-ueditor-wrap也会在 JS 加载失败时通过 console 输出它试图去加载的资源文件的完整路径,你可以借此分析如何填写。当需要区分环境时,你可以通过判断 process.env.NODE_ENV 来分别设置。

上面的创建过程在vue-cli2中是可以正常使用的

vue-cli3的区别

  1. 将下载好的压缩包解压并命名为UEditor放入你的public目录下
  2. 配置UEDITOR_HOME_URL的时候写成'/UEditor/',
  3. 不用更改ZeroClipboard.js里面的内容,如果还是报ZeroClipboard is not defined,那就根据上面的步骤修改即可

成功后的样子

综上

错误一个一个解决,不要跳步骤,看清报错的是什么

一定一定一定要注意路径问题