Vue中添加Quill富文本插件

一. 安装Quill富文本和扩展包

npm install vue-quill-editor quill-image-extend-module vue-quill-editor-upload quill-image-resize-module --save
富文本 图片**插件 图片上传插件 图片可调整大小插件 
还有个图片拖拽上传插件,项目中没有这个需求,引入打包还会报错,占时没有添加

二. 添加配置

  1. 全局引入css样式

    1
    2
    3
    4
    5
    // main.js
    // 引入富文本样式
    import 'quill/dist/quill.core.css';
    import 'quill/dist/quill.snow.css';
    import 'quill/dist/quill.bubble.css';
  2. 在需要使用富文本页面添加引用依赖

    1
    2
    3
    4
    5
    6
    7
    //**.vue页面(建议封装成组件,后面有封装过程)
    import {quillEditor, Quill} from 'vue-quill-editor';
    import {container, ImageExtend, QuillWatch,} from 'quill-image-extend-module';
    import {quillRedefine} from 'vue-quill-editor-upload';
    import ImageResize from 'quill-image-resize-module' // 调整图片大小组件。
    Quill.register('modules/ImageExtend', ImageExtend);
    Quill.register('modules/ImageResize', ImageResize )
  3. 在组件中注册和添加富文本配置信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    data:{
    return {
    context:'',
    // 富文本框参数设置
    editorOption: {
    modules: {
    ImageExtend: { // 如果不作设置,即{} 则依然开启复制粘贴功能且以base64插入
    name: 'fileFile', // 图片参数名
    size: 5, // 可选参数 图片大小,单位为M,1M = 1024kb
    action:'', // 服务器地址, 如果action为空,则采用base64插入图片
    // response 为一个函数用来获取服务器返回的具体图片地址
    // 例如服务器返回{code: 200; data:{ url: 'baidu.com'}} 则 return res.data.url
    response: (res) => {// 图片上传成功或错误 回调方法 成功后将图片地址return出去
    return res.filePath;
    },
    headers: (xhr) => { // 可选参数 设置请求头部
    // xhr.setRequestHeader('Content-Type','multipart/form-data')
    },
    sizeError: () => {}, // 图片超过大小的回调
    start: () => {}, // 可选参数 自定义开始上传触发事件
    end: () => {}, // 可选参数 自定义上传结束触发的事件,无论成功或者失败
    error: () => {}, // 可选参数 上传失败触发的事件
    success: () => {
    }, // 可选参数 上传成功触发的事件
    change: (xhr, formData) => {
    // xhr.setRequestHeader('myHeader','myValue')
    // formData.append('token', 'myToken')
    } // 可选参数 每次选择图片触发,也可用来设置头部,但比headers多了一个参数,可设置formData
    },
    toolbar: { // 如果不上传图片到服务器,此处不必配置
    container: container, // container为工具栏,此次引入了全部工具栏,也可自行配置
    handlers: {
    'image': function (value) { // 劫持原来的图片点击按钮事件 自定义图片上传
    // if (value) {
    // // 触发input框选择图片文件
    // document.querySelector('.avatar-uploader input').click()
    // } else {
    // this.quill.format('image', false);
    // }
    QuillWatch.emit(this.quill.id)
    }
    }
    },
    ImageResize: { //调整上传过后图片大小配置。
    displayStyles: {
    backgroundColor: 'black',
    border: 'none',
    color: 'white'
    },
    modules: [ 'Resize', 'DisplaySize','Toolbar' ]
    },
    },
    },
    }
    }
    // 注册组件
    components: { quillEditor }

    // 在页面中使用
    <template>
    <div>
    <quill-editor v-model="context" ref="myQuillEditor" :options="editorOption" ></quill-editor>
    </div>
    </template>
  4. 你认为成功了?NoNoNo!!! 你会报出一个错误,就是下面这个,
    TypeError: Cannot read property ‘imports’ of undefined
    错误提示
    错误原因: 引用图片调整大小的插件引起的, Quill还没有在window上挂在 webpack编译已经结束了
    如何解决:

    适用于Vue-cli2.x
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //在webpack.base.conf.js文件下
    1. 添加:
    const webpack=require('webpack');
    2. module.exports = {
    context: path.resolve(__dirname, '../'),
    entry:{},
    output:{},
    // 在这里添加 请不要放在output前面 那样会报错
    plugins: [
    new webpack.ProvidePlugin({
    'window.Quill': 'quill/dist/quill.js',
    'Quill': 'quill/dist/quill.js'
    }),
    ],
    resolve:{},
    ···
    }
适用于Vue-cli3.x&Vue-cli4.x&
1
2
3
4
5
6
7
8
9
10
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
"window.Quill": "quill/dist/quill.js",
Quill: "quill/dist/quill.js"
})
]
},

配置
修改了配置文件我们重新启动下项目 npm run dev
如果上传了图片四周出现了小’脚’那么说明你就成功了 试试放大,缩小它
成功

三.封装成组件

  1. 还没有结束!这么多的配置,没个评论都要用这个富文,每个页面都复制粘贴这么庞大的代码岂不累死我。封装它,弄成组件。盘它

    1. 将刚刚完成的页面改个响亮的名字 ===> quill.vue

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      // 给富文本标签添加input事件(每次输入都会调用下这个方法)
      <template>
      <div>
      <quill-editor v-model="context" ref="myQuillEditor" :options="editorOption"
      @input="$emit('update:value', $event)"
      >
      </quill-editor>
      </div>
      </template>

      export default {
      // 添加props接受父组件传来的值,
      props:{
      value:{
      type:String,
      },
      },
      // watch 方法是为了父组件传给子组件新的值 子组件自动更新最新的值
      watch: {
      value(newVAlue){
      console.log(newVAlue);
      this.context = newVAlue;
      },
      },
      }
    2. 在父组件中调用

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      <template>
      <div>
      <quill :value.sync="value"></quill>
      </div>
      </template>

      <script>
      import Quill from '@/components/quill.vue'
      export default {
      data() {
      return {
      value:'你好世界'
      }
      },
      components: { Quill }
      }
      </script>
    3. 如果你不仔细发现 你会觉得你成功了===> 数据无法回显
      页面一打开我们一开始给的默认值没有显示在富文本里面,这要是回显评论全是空呀。
      如何解决:

      1
      2
      3
      4
      5
      //在子组件中
      // 页面挂在到DOM树后 对富文本内的v-model赋一次值
      mounted () {
      this.context = this.value;
      },
    4. 最后的成果图
      成功

  2. 节省大家复制粘贴时间,最后整个组件长这个样子
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    <!-- 页面 -->
    <template>
    <div>
    <quill-editor
    v-model="context"
    ref="myQuillEditor"
    :options="editorOption"
    @input="$emit('update:value', $event)"
    >
    </quill-editor>
    </div>
    </template>

    <script>
    import {quillEditor, Quill} from 'vue-quill-editor';
    import {container, ImageExtend, QuillWatch,} from 'quill-image-extend-module';
    import {quillRedefine} from 'vue-quill-editor-upload';
    import ImageResize from 'quill-image-resize-module';
    Quill.register('modules/ImageResize', ImageResize )
    Quill.register('modules/ImageExtend', ImageExtend);
    export default {
    mounted () {
    this.context = this.value;
    },
    props:{
    value:{
    type:String,
    },
    },
    data() {
    return {
    context:'',
    // 富文本框参数设置
    editorOption: {
    modules: {
    ImageExtend: { // 如果不作设置,即{} 则依然开启复制粘贴功能且以base64插入
    name: 'fileFile', // 图片参数名
    size: 5, // 可选参数 图片大小,单位为M,1M = 1024kb
    action:'', // 服务器地址, 如果action为空,则采用base64插入图片
    // response 为一个函数用来获取服务器返回的具体图片地址
    // 例如服务器返回{code: 200; data:{ url: 'baidu.com'}} 则 return res.data.url
    response: (res) => {// 图片上传成功或错误 回调方法 成功后将图片地址return出去
    return res.filePath;
    },
    headers: (xhr) => { // 可选参数 设置请求头部
    // xhr.setRequestHeader('Content-Type','multipart/form-data')
    },
    sizeError: () => {}, // 图片超过大小的回调
    start: () => {}, // 可选参数 自定义开始上传触发事件
    end: () => {}, // 可选参数 自定义上传结束触发的事件,无论成功或者失败
    error: () => {}, // 可选参数 上传失败触发的事件
    success: () => {
    }, // 可选参数 上传成功触发的事件
    change: (xhr, formData) => {
    // xhr.setRequestHeader('myHeader','myValue')
    // formData.append('token', 'myToken')
    } // 可选参数 每次选择图片触发,也可用来设置头部,但比headers多了一个参数,可设置formData
    },
    toolbar: { // 如果不上传图片到服务器,此处不必配置
    container: container, // container为工具栏,此次引入了全部工具栏,也可自行配置
    handlers: {
    'image': function (value) { // 劫持原来的图片点击按钮事件 自定义图片上传
    // if (value) {
    // // 触发input框选择图片文件
    // document.querySelector('.avatar-uploader input').click()
    // } else {
    // this.quill.format('image', false);
    // }
    QuillWatch.emit(this.quill.id)
    }
    }
    },
    ImageResize: { //调整上传过后图片大小配置。
    displayStyles: {
    backgroundColor: 'black',
    border: 'none',
    color: 'white'
    },
    modules: [ 'Resize', 'DisplaySize','Toolbar' ]
    },
    },
    }
    }
    },
    methods: {
    },
    watch: {
    // 页面
    value(newVAlue){
    this.context = newVAlue;
    },
    },
    filters: {},
    computed: {},
    components: {
    quillEditor,
    quillRedefine,
    Quill
    }
    }
    </script>