日期: 2022 年 10 月 28 日

  • vue 引进quill-image-resize-module 报错TypeError: Cannot read property ‘imports’ of undefined

    首先说解决方案,不止一个,这里发我觉得比较好的一种。

    在webpack中添加ProvidePlugin,有两种情况。

    webpack.base.conf.js

    如果是vuecli2,则会有./build/webpack.base.conf.js这样的文件,添加方式:

    如果没有引入webpack则需要:

    const webpack = require('webpack')

    找到config下的plugins,添加如下代码:

    plugins: [
       new webpack.ProvidePlugin({
           'window.Quill': 'quill/dist/quill.js',
           'Quill': 'quill/dist/quill.js'
     })
    ]

    vue.config.js

    对于vuecli3,则直接在vue.config.js中找到chainWebpack,添加

    chainWebpack: config => {
        // quill-image-resize-module插件报错imports
        config.plugin('provide').use(webpack.ProvidePlugin, [{
          'window.Quill': 'quill/dist/quill.js',
          Quill: 'quill/dist/quill.js'
        }])
    }

    回过来说一下quill的两种引入方式,一种是直接使用quill,一种是使用vue-quill-editor。

    quill

    <template>
      <div ref="editor"></div>
    </template>
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'
    import Quill from 'quill'
    import { ImageDrop } from 'quill-image-drop-module'
    import ImageResize from 'quill-image-resize-module'
    Quill.register('modules/imageDrop', ImageDrop)
    Quill.register('modules/imageResize', ImageResize)
        data() {
        return {
          quill: undefined,
          currentValue: '',
          options: {
            theme: 'snow',
            bounds: document.body,
            debug: 'warn',
            modules: {
              toolbar: [
                ['bold', 'italic', 'underline', 'strike'],
                ['blockquote', 'code-block'],
                [{ list: 'ordered' }, { list: 'bullet' }],
                // [{ 'script': 'sub' }, { 'script': 'super' }],
                [{ indent: '-1' }, { indent: '+1' }],
                // [{ 'direction': 'rtl' }],
                // [{ size: ['small', false, 'large', 'huge'] }],
                [{ header: [1, 2, 3, 4, 5, 6, false] }],
                [{ color: [] }, { background: [] }],
                // [{ 'font': [] }],
                [{ align: [] }],
                ['clean'],
                ['link', 'image']
              ],
              imageDrop: true,
              imageResize: {}  //注意这里的首字母小写,组件官方文档是大写开头,会报错quill Cannot import ImageResize. Are you sure it was registered?
            },
            placeholder: '书写你的内容',
            readOnly: false
          }
        }
      },
      mounted() {
        this.init()
      },
      methods: {
        init() {
          const editor = this.$refs.editor
          // 初始化编辑器
          this.quill = new window.Quill(editor, this.options)
          // 默认值
          this.quill.pasteHTML(this.currentValue)
          // 绑定事件
          this.quill.on('text-change', (delta, oldDelta, source) => {
            const html = this.$refs.editor.children[0].innerHTML
            const text = this.quill.getText()
            const quillSelf = this.quill
            // 更新内部的值
            this.currentValue = html
            // 发出事件 v-model
            this.$emit('input', html)
            // 发出事件
            this.$emit('change', { html, text, quillSelf })
          })
          // 将一些 quill 自带的事件传递出去
          this.quill.on('text-change', (delta, oldDelta, source) => {
            this.$emit('text-change', delta, oldDelta, source)
          })
          this.quill.on('selection-change', (range, oldRange, source) => {
            this.$emit('selection-change', range, oldRange, source)
          })
          this.quill.on('editor-change', (eventName, ...args) => {
            this.$emit('editor-change', eventName, ...args)
          })
        }
      }

    vue-quill-editor

    <template>
      <div class="hello">
         <quill-editor v-model="content"
                          :options="editorOption"
                          @blur="onEditorBlur($event)"
                          @focus="onEditorFocus($event)"
                          @ready="onEditorReady($event)">
            </quill-editor>
        </div>
    </template>
    
    <script>
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'
    import Quill from 'quill'
    import { quillEditor } from 'vue-quill-editor'
    import { ImageDrop } from 'quill-image-drop-module'
    import ImageResize from 'quill-image-resize-module'
    Quill.register('modules/imageDrop', ImageDrop)
    Quill.register('modules/imageResize', ImageResize)
    
    //自定义字体类型
    var fonts = [
      "SimSun",
      "SimHei",
      "Microsoft-YaHei",
      "KaiTi",
      "FangSong",
      "Arial",
      "Times-New-Roman",
      "sans-serif"
    ];
    var Font = Quill.import("formats/font");
    Font.whitelist = fonts; //将字体加入到白名单
    Quill.register(Font, true);
    
    export default {
      name: 'HelloWorld',
      components: {
        quillEditor
      },
      data () {
        return {
          contentCode:'',
          content: `<p><img src="http://t8.baidu.com/it/u=1484500186,1503043093&fm=79&app=86&size=h300&n=0&g=4n&f=jpeg?sec=1581398243&t=ccf50d7b4dd50dac437d46e368b66b20" width="500"></p>
             `,
         editorOption: {
            modules: {
              toolbar: [
                ['bold', 'italic', 'underline', 'strike', 'image'],
                ['formula', 'clean'],
                ['blockquote', 'code-block'],
                [{'list': 'ordered'}, {'list': 'bullet'}],
                [{'script': 'sub'}, {'script': 'super'}],
                [{'size': ['small', false, 'large', 'huge']}],
                [{ 'font': fonts }],
                [{'header': [1, 2, 3, 4, 5, 6, false]}],
                [{ 'color': [] }, { 'background': [] }],
                [{ 'align': [] }],
                [{'direction': 'rtl'}]
              ],
              history: {
                  delay: 1000,
                  maxStack: 50,
                  userOnly: false
                },
                imageDrop: true,
                imageResize: {
                  displayStyles: {
                    backgroundColor: 'black',
                    border: 'none',
                    color: 'white'
                  },
                  modules: [ 'Resize', 'DisplaySize', 'Toolbar' ]
                }
            },
            placeholder: '输入内容........'
          }
        }
      },
      methods: {
        //vue-quill-editor
        onEditorBlur(quill) {
          // console.log("editor blur!", quill, this.content);
          //this.$emit("editorBlur", this.content);
          this.contentCode=this.content
        },
        onEditorFocus(quill) {
          this.contentCode=this.content
        },
        onEditorReady(quill) {
          // console.log("editor ready!", quill);
        },
        onEditorChange({ quill, html, text }) {
          // console.log("editor change!", quill, html, text);
          this.content = html;
        },
        onEditorChange(quill) {
          // console.log("编辑内容改变!", quill, this.content);
          //this.$emit("editorBlur", this.content);
        },
      },
      mounted() {
        //  console.log("this is current quill instance object", this.editor);
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped lang='scss'>
    </style>