从0.8开发一个vue的插件。

需求:在vue项目中使quill富文本编辑器支持图片上传功能。

思路:修改quill.js的重新编译vue-quill-editor

1.在GitHub上下载quill.js 的源码https://github.com/quilljs/quill

2.在本地新建myQuill项目。

  从Quill的使用文档中我们知道了在实例化Quill时传了两个参数,一个是个选择器第二个是配置参数options,

所以我们将上传文件的地址添加在配置参数options中,命名为upload。

  根据官网的例子在点击图片上传按钮时会插入input的文件域

  所以我们在qiull.js文件中搜索“image/png, image/gif, image/jpeg, image/bmp, image/x-icon”关键字

就会找到这么一段代码,我这个是压缩过的min版本

 image: function() {
                            var t = this
                              , e = this.container.querySelector("input.ql-image[type=file]");
                            null == e && (e = document.createElement("input"),
                            e.setAttribute("type", "file"),
                            e.setAttribute("accept", "image/png, image/gif, image/jpeg, image/bmp, image/x-icon"),
                            e.classList.add("ql-image"),
                            e.addEventListener("change", function() {
                                if (null != e.files && null != e.files[0]) {
                                    var n = new FileReader;
                                    n.onload = function(n) {
                                        var r = t.quill.getSelection(!0);
                                        t.quill.updateContents((new d.default).retain(r.index).delete(r.length).insert({
                                            image: n.target.result
                                        }), v.default.sources.USER),
                                        t.quill.setSelection(r.index + 1, v.default.sources.SILENT),
                                        e.value = ""
                                    }
                                    ,
                                    n.readAsDataURL(e.files[0])
                                }
                            }),
                            this.container.appendChild(e)),
                            e.click()
                        },

  这段代码主要说的是插入资格y一个input框,并设置一些属性,并绑定一个change事件,并实例化一个FileReader对象,然后通过对象的onload事件的回调函数的第一个参数的target.result属性就能拿到当前选中图片的base64为的值,这个值直接可以赋值个img的src属性,一般图片预览就是这么实现的。

  所以我们只需要将这个n.target.result替换成我们服务器端返回的图片地址就可以了。在这就会有人问,为什么不直接上传base64数据,要换成图片地址,那是因为普通的post携带数据大小是有限制的,小图片是可以这样做,大图片就不行了。

  现在回到我们自己的Myquill项目中,全局搜索new FileReader(),会在两个文件中用到每一个是dist文件,这个是打包过的,不管。还有一个是modules/uploader.js,所以我们就在这改。

  在这没有用原生的ajax请求,用到的是axios。

  1.安装axios => npm i axios

  2.更改core/module.js

import axios from 'axios';

class Module {
  constructor(quill, options = {}) {
    this.quill = quill;
    this.options = options;
    const config = {
      timeout: 60 * 1000, // Timeout
      headers: this.quill.options.headers || {},自定义请求头
    };
    const _axios = axios.create(config);
    _axios.interceptors.response.use(
      response => {
        return response.data;
      },
      error => {
        // Do something with response error
        return Promise.reject(error);
      },
    );
    this.$http = _axios;
  }
}

Module.DEFAULTS = {};

export default Module;

  3.更改modules/uploader.js下的Uploader.DEFAULTS 对象的handler方法中的const promises改为

    const promises = files.map(file => {
      return new Promise(async resolve => {
        let res1;
        if (this.quill.options.upload) {
          res1 = await this.$http.get(this.quill.options.upload);
        }
        if (res1 && res1.msg === 'quilljs') {
          const format = new FormData();
          format.append('img', file);
          const res = await this.$http.post(this.quill.options.upload, format);
          if (res.url) {
            resolve(res.url);
          } else {
            const reader = new FileReader();
            reader.onload = e => {
              resolve(e.target.result);
            };
            reader.readAsDataURL(file);
            console.log(
              '%c后端配置有误!请在对应的地址上返回真确的数据',
              'color: red',
            );
          }
        } else {
          const reader = new FileReader();
          reader.onload = e => {
            resolve(e.target.result);
          };
          reader.readAsDataURL(file);
        }
      });
    });

我自己设置的规则是:get请求返回{msg: quilljs},post请求返回{url: '图片的地址'}

  4.将_develop/webpack.config.js的baseConfig.node设为production ,默认为development开发模式,这样对大大减小打包的体积

  5.运行npm run build:webpack得到dist/quill.js

3.在GitHub现在vue-quill-editor的源码https://github.com/cfj1996/vue-quill-img-editor

  1.新建vue-quill-my-editor本地项目将vue-quill-editor的代码解压到本地项目中

  2.package.json中的name改为自己想要的名字如:my-quill-editor,删除private,license,注意main配置项,这个是在我们import 引包是指项的文件,如果要改要与webpack配置的打包输出文件路径,文件名匹配。

  3.新建plugins文件夹,将我们上一个myQuill中的项目中打包的qiull.js复制过来,

  4.更改src/editor.vue文件

    将原先的import _Quill from 'quill'改为import _Quill from '../plugins/quill'

    添加props下的upload: String,headers: {type: Object,default: () => ({})}

    在initialize方法中改this._options = Object.assign({upload: this.upload, headers: this.headers}, this.defaultOptions, this.globalOptions, this.options)

  5.更改src/index.js

    将原先的import _Quill from 'quill'改为import _Quill from '../plugins/quill'

  6.运行npm run build ,打包项目

  7.运行npm link 将包my-quill-editor链接到全局方便本地测试

  8.如果想上传到npm上请自行百度。

4.本地测试项目包

  1.用vue-cli3.0新建一个项目,

  2.将babel.config.js改为

module.exports = {
  presets: [
      ['@vue/app',{modules: 'umd', useBuiltIns: 'entry'}]
  ]
}

  3.运行npm link my-quill-editor 将刚刚链接的全局my-quill-editor包再链接带项目依赖中。

  4.运行npm i quill

  4.设置代理vue.config.js

  

// vue.config.js
module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://127.0.0.1:7001/',// 我的后端接口为127.0.0.1:7001
                changeOrigin: true,
                pathRewrite: {
                    '^/api': ''
                },
            }
        }
    }
}

  5.在main.js中添加   

import Editor from 'my-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
Vue.use(Editor, {upload: '/api/quillImgUpload'})

由于我们在my-quill-editor项目中的src/index.js 中有Vue.component(quillEditor.name, quillEditor)

其中quillEditor.name就是quill-editor,所以我们就可以在其他的组件中用quill-editor 组件了

  6.用node 的egg.js或者其他的后端语言新建一个后端接口

    接口名为quillImgUpload

    get请求返回值{code: 200, msg: 'quilljs',}

    post请求返回值:{code: 200,url: '图片地址‘,}

5.注意事项

在本地测试的时候一定要在babel.config.js中添加{modules: 'umd', useBuiltIns: 'entry'},由于vue的项目中找不到exports,根据webpack打包的规则,引入的模块就会挂载在的window上。

猜你喜欢

转载自www.cnblogs.com/iwebcc/p/10965927.html