vue-富文本/自定义上传图片

1、下载组件

npm install vue-quill-editor –D

2、在需要的组件内引入富文本

import { quillEditor } from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

components: {
    quillEditor
  }

<quill-editor
        ref="QuillEditor"
        v-model="editorContent"
        class="myQuillEditor"
        :options="editorOption"
        @change="editorChange($event)">
        </quill-editor>

3、基本配置

const toolbarOptions = [
      ['bold', 'italic', 'underline', 'strike'],        // toggled buttons
      ['blockquote', 'code-block'],

      [{'header': 1}, {'header': 2}],               // custom button values
      [{'list': 'ordered'}, {'list': 'bullet'}],
      [{'script': 'sub'}, {'script': 'super'}],      // superscript/subscript
      [{'indent': '-1'}, {'indent': '+1'}],          // outdent/indent
      [{'direction': 'rtl'}],                         // text direction

      [{'size': ['small', false, 'large', 'huge']}],  // custom dropdown
      [{'header': [1, 2, 3, 4, 5, 6, false]}],

      [{'color': []}, {'background': []}],          // dropdown with defaults from theme
      [{'font': []}],
      [{'align': []}],
      ['link', 'image', 'video'],
      ['clean']                                         // remove formatting button
    ]

export default {
  props: {
    editorContent: String
  },
  components: {
    Upload,
    quillEditor
  },
  data () {
    return {
      editorOption: {
        theme: 'snow',
        modules: {
          toolbar: {
            container: toolbarOptions,  // 工具栏
            handlers: {
                'image': function (value) {
                    if (value) {
                        document.querySelector('.el-upload-dragger button').click()
                    } else {
                        this.quill.format('image', false);
                    }
                }
            }
          }
        },
        placeholder: '请输入...',
        readOnly: false
      },
      // 七牛
      qiNiuObj: {
        header: {
          Authorization: ''
        },
        label: '',
        limit: 100,
        accept: '.jpg,.png',
        btnName: '上传图片',
        QiniuData: {
          key: "", //图片名字处理
          token: "" //七牛云token
        },
        domain: "", // 七牛云的上传地址
        qiniuaddr: "", // 七牛云的图片外链地址
        uploadPicUrl: "", //提交到后台图片地址
        fileList: [] // 图片列表
      }
    }
  },
  methods: {
    editorChange ({editor,html,text}) {
      this.$emit('editorChange', {html,text})
    },
    // 七牛,
    getQiNiuUrl (obj) {
      this.qiNiuObj.uploadPicUrl = obj.uploadUrl.join(',')
      // 富文本内图片
      let quill = this.$refs.QuillEditor.quill
      let length = quill.getSelection().index;
      quill.insertEmbed(length, 'image', obj.response)
      quill.setSelection(length + 1)
    },
    async getQiNiu() { // 获取七牛云token
      const res = await this.$api.hotelHost.getQiNiu({})
      if (res.data.code == 200) {
        this.qiNiuObj.QiniuData.token = res.data.data.token
        this.qiNiuObj.domain = res.data.data.upHost
        this.qiNiuObj.qiniuaddr = res.data.data.domain
      } else {
        this.$message.error(res.data.msg)
      }
    },
  },
  computed: {

  },
  watch: {

  },
  created () {
    this.getQiNiu()
  },
  mounted () {

  },
}
基本配置

4、css配置

.editor {
  line-height: normal !important;
  width: 930px;
  margin: 0 auto;
}
.ql-container {
  height: 400px !important;
}
.ql-snow .ql-tooltip[data-mode=link]::before {
  content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
    border-right: 0px;
    content: '保存';
    padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode=video]::before {
    content: "请输入视频地址:";
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: '14px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before {
  content: '12px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before {
  content: '18px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before {
  content: '32px';
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: '文本';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: '标题1';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: '标题2';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: '标题3';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: '标题4';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: '标题5';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: '标题6';
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: '标准字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before {
  content: '衬线字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before {
  content: '等宽字体';
}
.Editor__upload{
  width: 0;
  height: 0;
  overflow: hidden;
  opacity: 0;
  margin-bottom: 0!important;
}
css配置

5、全部代码

<!-- 富文本编辑器 -->
<template>
  <div class=''>
    <el-card>
      <Upload :qiNiuObj="qiNiuObj" @changeUrl="getQiNiuUrl" class="Editor__upload"></Upload>
      <quill-editor
        ref="QuillEditor"
        v-model="editorContent"
        class="myQuillEditor"
        :options="editorOption"
        @change="editorChange($event)">
        </quill-editor>
    </el-card>
  </div>
</template>

<script>
import Upload from '@components/Upload.vue'
import { quillEditor } from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

const toolbarOptions = [
      ['bold', 'italic', 'underline', 'strike'],        // toggled buttons
      ['blockquote', 'code-block'],

      [{'header': 1}, {'header': 2}],               // custom button values
      [{'list': 'ordered'}, {'list': 'bullet'}],
      [{'script': 'sub'}, {'script': 'super'}],      // superscript/subscript
      [{'indent': '-1'}, {'indent': '+1'}],          // outdent/indent
      [{'direction': 'rtl'}],                         // text direction

      [{'size': ['small', false, 'large', 'huge']}],  // custom dropdown
      [{'header': [1, 2, 3, 4, 5, 6, false]}],

      [{'color': []}, {'background': []}],          // dropdown with defaults from theme
      [{'font': []}],
      [{'align': []}],
      ['link', 'image', 'video'],
      ['clean']                                         // remove formatting button
    ]

export default {
  props: {
    editorContent: String
  },
  components: {
    Upload,
    quillEditor
  },
  data () {
    return {
      editorOption: {
        theme: 'snow',
        modules: {
          toolbar: {
            container: toolbarOptions,  // 工具栏
            handlers: {
                'image': function (value) {
                    if (value) {
                        document.querySelector('.el-upload-dragger button').click()
                    } else {
                        this.quill.format('image', false);
                    }
                }
            }
          }
        },
        placeholder: '请输入...',
        readOnly: false
      },
      // 七牛
      qiNiuObj: {
        header: {
          Authorization: ''
        },
        label: '',
        limit: 100,
        accept: '.jpg,.png',
        btnName: '上传图片',
        QiniuData: {
          key: "", //图片名字处理
          token: "" //七牛云token
        },
        domain: "", // 七牛云的上传地址
        qiniuaddr: "", // 七牛云的图片外链地址
        uploadPicUrl: "", //提交到后台图片地址
        fileList: [] // 图片列表
      }
    }
  },
  methods: {
    editorChange ({editor,html,text}) {
      this.$emit('editorChange', {html,text})
    },
    // 七牛,
    getQiNiuUrl (obj) {
      this.qiNiuObj.uploadPicUrl = obj.uploadUrl.join(',')
      // 富文本内图片
      let quill = this.$refs.QuillEditor.quill
      let length = quill.getSelection().index;
      quill.insertEmbed(length, 'image', obj.response)
      quill.setSelection(length + 1)
    },
    async getQiNiu() { // 获取七牛云token
      const res = await this.$api.hotelHost.getQiNiu({})
      if (res.data.code == 200) {
        this.qiNiuObj.QiniuData.token = res.data.data.token
        this.qiNiuObj.domain = res.data.data.upHost
        this.qiNiuObj.qiniuaddr = res.data.data.domain
      } else {
        this.$message.error(res.data.msg)
      }
    },
  },
  computed: {

  },
  watch: {

  },
  created () {
    this.getQiNiu()
  },
  mounted () {

  },
}
</script>

<style lang='scss'>
.editor {
  line-height: normal !important;
  width: 930px;
  margin: 0 auto;
}
.ql-container {
  height: 400px !important;
}
.ql-snow .ql-tooltip[data-mode=link]::before {
  content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
    border-right: 0px;
    content: '保存';
    padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode=video]::before {
    content: "请输入视频地址:";
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: '14px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before {
  content: '12px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before {
  content: '18px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before {
  content: '32px';
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: '文本';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: '标题1';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: '标题2';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: '标题3';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: '标题4';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: '标题5';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: '标题6';
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: '标准字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before {
  content: '衬线字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before {
  content: '等宽字体';
}
.Editor__upload{
  width: 0;
  height: 0;
  overflow: hidden;
  opacity: 0;
  margin-bottom: 0!important;
}
</style>
Editor组件
posted @ 2023-11-17 16:40  忙着可爱呀~  阅读(92)  评论(0)    收藏  举报