vue 使用 vue-quill-editor 富文本编辑器,及对其改造为图片自动上传至图片服务器

 博主是在element-admin 模板中使用的:

引入编辑器:

npm install vue-quill-editor

 在你需要编辑器的页面引入它:

import "quill/dist/quill.core.css"
import "quill/dist/quill.snow.css"
import "quill/dist/quill.bubble.css"

import { quillEditor } from "vue-quill-editor"

 注册使用:

 components: {
    quillEditor
  },

页面引用:

<quill-editor ref="text" v-model="content" class="myQuillEditor" :options="editorOption" />

 对应数据绑定:

components: {
    quillEditor
  },
data () {
  return {
    content: '',
    editorOption: {} 
  }
},

至此就可以正常使用了:

 

数据能够很好以text的格式的存储在mysql中(服务器格式为String),但是直接存储的图片是以base64转码后直接存储的,因为容量大小,读取速度等关系所以直接存储并不太合适

一般情况下都是把图片等资源存储在其他地方,以cdn或者oss的方式进行远程调用,博主用的是阿里云oss,没有的话临时可以自己用Nginx搭建个伪CDN服务器。

下面开始改造:

(改造是从一位大佬那里学习的,自己根据环境实际改造了下,大佬博客:https://blog.csdn.net/lyj2018gyq/article/details/82585194

首先是引用页面的标签精简改造(相对于大佬我又添加了字体颜色和代码块,感觉还是比较有用):

    <el-form-item label="简介" style="height:500px;">
        <quilleditor
          v-model="courseInfo.description"
          ref="myTextEditor"
          :options="editorOption"
          @change="onChange"
          style="height:400px;"
        >
          <div id="toolbar" slot="toolbar">
            <select class="ql-size">
              <option value="small"></option>
              <!-- Note a missing, thus falsy value, is used to reset to default -->
              <option selected></option>
              <option value="large"></option>
              <option value="huge"></option>
            </select>

          <!--颜色种类自己添加-->
            <select class="ql-color">
              <option value="red"></option>
              <option value="black" selected></option>
              <option value="yellow"></option>
              <option value="blue"></option>
              <option value="#003366"></option>
              <option value="#148866"></option>
            </select>

            <!-- Add subscript and superscript buttons -->
            <span class="ql-formats">
              <button class="ql-script" value="sub"></button>
            </span>
            <span class="ql-formats">
              <button class="ql-script" value="super"></button>
            </span>
            <span class="ql-formats">
              <button type="button" class="ql-bold"></button>
            </span>
            <span class="ql-formats">
              <button type="button" class="ql-italic"></button>
            </span>
            <span class="ql-formats">
              <button type="button" class="ql-blockquote"></button>
            </span>
            <span class="ql-formats">
              <button type="button" class="ql-list" value="ordered"></button>
            </span>
            <span class="ql-formats">
              <button type="button" class="ql-list" value="bullet"></button>
            </span>
            <span class="ql-formats">
              <button type="button" class="ql-link"></button>
            </span>
            <span class="ql-formats">
              <button class="ql-code-block"></button>
            </span>
            <span class="ql-formats">
              <button type="button" @click="imgClick" style="outline:none">
                <svg viewBox="0 0 18 18">
                  <rect class="ql-stroke" height="10" width="12" x="3" y="4" />
                  <circle class="ql-fill" cx="6" cy="7" r="1" />
                  <polyline
                    class="ql-even ql-fill"
                    points="5 12 5 11 7 9 8 10 11 7 13 9 13 12 5 12"
                  />
                </svg>
              </button>
            </span>
            <span class="ql-formats">
              <button type="button" class="ql-video"></button>
            </span>
          </div>
        </quilleditor>
      </el-form-item>

 然后是引入依赖:

import courseApi from "@/api/edu/course" // element-admin模板集成了接口调用,这里是上传图片的axios方法所在文件的引用

import "quill/dist/quill.core.css"
import "quill/dist/quill.snow.css"
import "quill/dist/quill.bubble.css"

import { quillEditor } from "vue-quill-editor"

course.js里面的axios方法:

import request from '@/utils/request'

export default {
    uploadFile(file) {
        return request({
            url: `/service-oss/file/upload`,
            method: 'post',
            data: file
        })
    }
}

文本页数据+方法: 

export default {
  name: "v-editor",
  props: {
    value: {
      type: String
    },
    /*上传图片的file控件name*/
    fileName: {
      type: String,
      default: "file"
    },
    maxUploadSize: {
      type: Number,
      default: 1024 * 500
    }
  },
  data() {
    return {
      courseInfo: {
        description: "",
      },
      editorOption: {
        // some quill options
        modules: {
          toolbar: "#toolbar"
        }
      }
    };
  },
  created() {
  },
  methods: {
    onChange() {
      this.$emit("input", this.courseInfo.description);
    },
    /*选择上传图片切换*/
    onFileChange(e) {
      var fileInput = e.target;
      if (fileInput.files.length === 0) {
        return;
      }
      this.editor.focus();
      if (fileInput.files[0].size > this.maxUploadSize) {
        this.$message.error("图片不能大于500KB");
        return;
      }
      var data = new FormData();
      data.append(this.fileName, fileInput.files[0]);
      courseApi.uploadFile(data).then(res => {
        if (res.data) {
          this.editor.insertEmbed(
            this.editor.getSelection().index,
            "image",
            res.data.url //"url" 对应后台返回的图片地址对应的key
          );
        }
      });
    },
    /*点击上传图片按钮*/
    imgClick() {
      /*内存创建input file*/
      var input = document.createElement("input");
      input.type = "file";
      input.name = this.fileName;
      input.accept = "image/jpeg,image/png,image/jpg,image/gif";
      input.onchange = this.onFileChange;
      input.click();
    }
  },
  computed: {
    editor() {
      return this.$refs.myTextEditor.quill;
    }
  },
  components: {
    quilleditor: quillEditor
  },
  mounted() {
    this.courseInfo.description = this.value;
  },
  watch: {
    value(newVal, oldVal) {
      if (this.editor) {
        if (newVal !== this.courseInfo.description) {
          this.courseInfo.description = newVal;
        }
      }
    }
  }
}

 测试下:

 测试OK,取值回显也是没问题的!

 

 此处的富文本编辑器去除了多余的功能,下面是该富文本全部功能,自己对照着可以选择性添加

(方法就是那个class样式,玄学程序员一猜就知道啦!๑乛◡乛๑)

toolbar: [
      ['bold', 'italic', 'underline', 'strike'],
      ['blockquote', 'code-block'],
      [{ 'header': 1 }, { 'header': 2 }],
      [{ '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', 'video']
    ]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章